Как подписаться на изменения состояния переменной react?

Почему при изменении переменной состояния currentPage он изменяется лишь в dom но не в коде и как с этим работать?

const ReactComponent = () => {
  const [currentPage, setCurrentPage] = useState(1);
    
  const fetchData = async () => {
     const response = await FetchDataService.get(currentPage); // не изменилось
  }
    
  const goNextPage = () => {
   setCurrentPage(currentPage + 1);
   fetchData();
  }
        
  const goPrevPage = () => {
   setCurrentPage(currentPage - 1);
   fetchData();
  }

  return(
   <section>
     <span>Строк: {pageSize}</span>
     <button onClick={goPrevPage}>{`< пред`}</button>
     <span>{currentPage} из {totalPages}</span>
     <button onClick={goNextPage}>{`след >`}</button>
   </section>
   )
}

Ответы (3 шт):

Автор решения: CrazyElf

currentPage поменяется при следующей отрисовке контрола, инициированной изменением currentPage через вызов setCurrentPage. Поэтому вам нужно запрашивать данные сразу при отрисовке контрола, а не тогда, когда вы вызываете setCurrentPage, чтобы поменять состояние переменной. То есть примерно так (надеюсь, этот код находится внутри контрола React, а не сам по себе):

const [currentPage, setCurrentPage] = useState(1);

// сама эта функция странная - её значение никуда не идёт, её нужно переписать
const fetchData = async () => {
    const response = await FetchDataService.get(currentPage); // не изменилось
}

fetchData(); // получаем текущее значение currentPage и используем его

const goNextPage = () => {
   setCurrentPage(x => x + 1); // лучше менять переменные так
}

const goPrevPage = () => {
   setCurrentPage(x => x - 1); // лучше менять переменные так
}

[...]

P.S. Засомневался, может я неправильно понимаю React, но нет, вот цитата из документации:

The set function only updates the state variable for the next render. If you read the state variable after calling the set function, you will still get the old value that was on the screen before your call.

Ну и там дальше про то, что если значение выставлено тоже самое, то компонент не обновится и т.д.

→ Ссылка
Автор решения: Grundy

если fetchData должен вызываться при изменении currentPage - нужно добавить useEffect с соответствующей зависимостью

const [currentPage, setCurrentPage] = useState(1);

useEffect(()=>{
    (async ()=>{
        const response = await FetchDataService.get(currentPage); // не изменилось
    })();
}, [currentPage]);

const goNextPage = () => {
   setCurrentPage(currentPage + 1);
}

const goPrevPage = () => {
   setCurrentPage(currentPage - 1);
}
→ Ссылка
Автор решения: SwaD

Изменение состояния компонента - это асинхронная операция и надеяться что setter отработает быстрее, чем следующая функция - не правильно.

Я вижу 2 варианта. Первый, сохранять "новое" значение в отдельную переменную и передавать в фукнцию для вызова:

const fetchData = async (newPage) => {
  const response = await FetchDataService.get(newPage); 
}

const goNextPage = () => {
  const newPage = ++currentPage;
  setCurrentPage(newPage);
  fetchData(newPage);
}

const goPrevPage = () => {
  const newPage = --currentPage;
  setCurrentPage(newPage);
  fetchData(newPage);
}

Либо в явном виде опираться на состояние переменных компонентов, подписавшись на их изменение с помощью useEffect

const goNextPage = () => {
  setCurrentPage(++currentPage);
}

const goPrevPage = () => {
  setCurrentPage(--currentPage);
}

useEffect(() => {
  FetchDataService.get(currentPage);
}, [currentPage]);
→ Ссылка