React useEffect不在依赖关系更改上运行

问题描述 投票:0回答:1

我想做什么

我有一个可供用户加入的大厅。为了在页面刷新上将已加入的大厅保留在客户端上,我决定将已加入的大厅放入浏览器的会话存储中。在此之前,useState不会通过页面刷新保持不变。

据我所知,“设置会话存储”被归类为副作用,应在useEffect中进行处理。问题是当我设置大厅时,将大厅作为从属关系的useEffect无法运行。

设置断点表明它根本没有运行,但是我可以看到joinedLobby已从undefined更改为对象(示例:{success: "Successfully joined ...", payload : { id:"", ...}})。

会话存储区为空。

设置应该更新useEffect的状态

  const { setJoinedLobby } = useContext(JoinedLobbyProviderContext);
  const history = useHistory();

  useEffect(() => {
    if (joinState.result === undefined) return;
    setJoinedLobby(joinState.result);
    history.push('/lobby');
  }, [joinState.result, history, setJoinedLobby]);

路由器内部的提供者

          <JoinedLobbyProviderContext.Provider
            value={{ getJoinedLobby, setJoinedLobby }}>
            <Route path='/play'>
              <Play />
            </Route>
            <Route path='/lobby'>
              <Lobby />
            </Route>
          </JoinedLobbyProviderContext.Provider>

提供商提供的功能

  const [joinedLobby, setJoinedLobby] = useState(undefined);

  useEffect(() => {
    if (joinedLobby === undefined) return;
    sessionStorage.setItem('joinedLobby', JSON.stringify(joinedLobby));
  }, [joinedLobby]);

  const getJoinedLobby = () => {
    return JSON.parse(sessionStorage.getItem('joinedLobby'));
  };

编辑:joinState.result如何更改


const joinInit = {
    errors: undefined,
    loading: false,
    result: undefined,
    id: undefined,
  };

  const joinReducer = (state, action) => {
    switch (action.type) {
      case 'joinLobby': {
        return { ...state, id: action.payload };
      }
      case 'loadingTrue':
        return { ...state, loading: true };
      case 'setResult':
        return { ...state, loading: false, result: action.payload };
      case 'setErrors':
        return {
          ...state,
          loading: false,
          errors: action.payload,
        };
      case 'reset':
        return joinInit;
      default : {throw new Error('Didn't find action passed to reducer')}
    }
  };

  const [joinState, joinStateDispatch] = useReducer(joinReducer, joinInit);

  const passRef = useRef();
  useEffect(() => {
    const joinLobby = async () => {
      joinStateDispatch({ type: 'loadingTrue' });
      try {
        const jsonResponse = await (
          await fetch(`${BACKEND_URL}/play/joinLobby/${joinState.id}`, {
            method: 'PATCH',
            credentials: 'include',
            headers: {
              'Content-type': 'application/json',
            },
            body: JSON.stringify({
              password: passRef.current.value,
            }),
          })
        ).json();
        joinStateDispatch({ type: 'setResult', payload: jsonResponse });
      } catch (e) {
        joinStateDispatch({ type: 'setErrors', payload: e });
      }
    };
    if (joinState.id !== undefined) {
      joinLobby();
    }
  }, [joinState.id, joinStateDispatch]);
javascript reactjs frontend client
1个回答
-1
投票

会话存储仅应用于存储与会话相关的数据,并且由于大小限制,它可能不存储值,请使用localStorage。它为您提供了巨大的4MB大小。您可以通过将对象数组转换为字符串来设置数据,如下所示:-

localStorage.setItem("joinState", JSON.stringify(joinState));

您可以按以下方式获取对象数组:-

JSON.parseJSON(localStorage.getItem("joinState"));

我希望这对您有帮助...

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.