Redux useSelector не обновляется, необходимо обновить - PullRequest
0 голосов
/ 30 апреля 2020

я сталкиваюсь с этой проблемой. когда у меня есть вызов Ax ios, который обещает отправить действие для обновления избыточного кода и выполнения обратного вызова. но когда выполняется обратный вызов, состояние избыточности кажется устаревшим.

я получил код песочницы для демонстрации здесь

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

Как получить правильное состояние редукции во время обратного вызова?

enter image description here

1 Ответ

1 голос
/ 30 апреля 2020

Ответ всегда будет устаревшим, вот как работают React-хуки. Они применяют замыкание ко всем переменным в каждом отдельном рендере при их создании. Если вам абсолютно необходимо, чтобы значение не было устаревшим в функции обратного вызова (или эффекте), установите для него ссылку.

const { response, getNewDate } = useResponse();
const responseRef = useRef(response);
useLayoutEffect(() => {
    responseRef.current = response;
}, [response]);
const callbackSuccessful = (data: IResponse) => {
    console.log("response is not Stale: " + responseRef.current.newDate);
    console.log("should be: " + data.newDate);
};

Как только вы установите ссылку, вы четко увидите, что ответ фактически изменяется, и responseRef.current показывает то же значение, что и data.newDate.

Вы должны использовать здесь LayoutEffect, потому что порядок, в котором выполняется эффект, является неправильным для обратного вызова. Поскольку useEffect запускается после повторного рендеринга компонента, в то время как useLayoutEffect выполняется во время повторного рендеринга компонента.

Еще один способ убедиться, что useSelector работает нормально и обновляется, и что ваш MyPages.tsx видит, что обновление - это useEffect регистрировать изменения всякий раз, когда они меняются.

useEffect(() => {
  console.log(response.newDate)
}, [response]);

Если вы хотите получить доступ к последнему состоянию избыточного хранилища в обратном вызове без каких-либо проблем с синхронизацией вообще, используйте UseStore, и он не вызывает повторного рендеринга. вообще.

const store = useStore();

const callbackSuccessful = (data: IResponse) => {
    console.log("should be: " + data.newDate);
    console.log("Redux store: " + store.getState().apiResponse.newDate);
};

https://codesandbox.io/s/react-typescript-demo-pek65?file= / src / pages / MyPages.tsx

...