Состояние React Hooks не обновляется - PullRequest
0 голосов
/ 18 марта 2019

Я пробую новые функции хуков и застрял на моем состоянии не обновляется.

На самом деле состояние обновляется (я вижу обновленные значения в console.log, и мой компонент повторно запускает useEffect), но метод useEffect использует мое старое состояние и сохраняет подпись только для первого пользователя, в то время как активный пользователь изменил в состоянии.

Я думал о добавлении useCallback и перемещении своих методов в useEffect или сам компонент, но мне удалось заставить его работать.

состояние:

const inititalState = {
  displayHolder: true,
  activeUser: 0,
  signatureDate: new Date().toLocaleDateString('he'),
};

это мое использованиеEffect:

useEffect(() => {
    try {
        ...
        canvas._canvas.addEventListener('mousedown', throttle(() => handleSignatureStart(dispatch), 500));
        canvas._canvas.addEventListener(
            'mouseup',
            throttle(() => handleSignatureEnd(activatedUser, name, canvas, onFinish), 500),
        );

        ...

        // set to new signature and date
        if (signature && typeof signature === 'string') {
            dispatch({ type: 'setSignatureDetails', payload: { displayHolder: false, signatureDate } });
            canvas.fromDataURL(signature);
        } else {
            dispatch({
                type: 'clearSignatureDetails',
                payload: { displayHolder: true, signatureDate: new Date().toLocaleDateString('he') },
            });
        }

        //umount
        return () => {
            if (canvas) {
                canvas._canvas.removeEventListener('mousedown', handleSignatureStart);
                canvas._canvas.removeEventListener('mouseup', handleSignatureEnd);
            }
        };
    } catch (error) {
        console.error(error);
    }
}, [dispatch]);

вот мой редуктор:

const signatureReducer = (state, { type, payload }) => {
    console.log('@@@@', type, '@@@');
    switch (type) {
        case 'setSignatureDetails': {
            const { displayHolder, signatureDate, activeUser } = payload;
            const activeUserReady = activeUser === 0 || activeUser ? activeUser : state.activeUser;
            console.log(activeUser, activeUserReady);
            return { ...state, displayHolder, signatureDate, activeUser: activeUserReady };
        }
        case 'clearSignatureDetails': {
            const { displayHolder, signatureDate } = payload;
            return { ...state, displayHolder, signatureDate };
        }
        case 'hidePlaceholder': {
            const { displayHolder } = payload;
            return { ...state, displayHolder };
        }
        case 'showPlaceholder': {
            const { displayHolder, activeUser } = payload;
            const activeUserReady = activeUser === 0 || activeUser ? activeUser : state.activeUser;
            console.log(activeUser, activeUserReady);
            return { ...state, displayHolder, activeUser: activeUserReady };
        }
        default:
            return state;
    }
};

родительское состояние:

  users: [
    {
      name: 'foo',
      forwhom: 0,
      signatures: {
        clientSignature: {
          value: ''
        }
      }
    },
    {
      name: 'bar',
      forwhom: 1,
      signatures: {
        clientSignature: {
          value: ''
        }
      }
    }
  ]

Вот та часть моего проекта, которая, возможно, демонстрирует мою проблему. https://stackblitz.com/edit/react-51j5i6

Спасибо

1 Ответ

0 голосов
/ 18 марта 2019

Сложно понять, каким должно быть ваше желаемое состояние из вашей демонстрации Но, насколько я понимаю, я считаю, что ваши useEffect зависимости должны быть такими:

useEffect(() => {
  ...
}, [activeUser]);

Пара других вещей; как заметил @Ryan Cogswell, вам не нужно переопределять activeUser внутри обратного вызова useEffect.

Кроме того, внутри вашего обратного вызова useEffect; если вы собираетесь запускать эту функцию при обновлении для активного пользователя (IE несколько раз), вы должны либо удалить прослушиватели событий, либо проверить, были ли добавлены прослушиватели, чтобы предотвратить добавление прослушивателей событий при каждом рендеринге.

...