使用钩子更新父组件状态后,子组件未重新渲染

3
我有一个功能组件 App 使用了 useEffect 钩子,我正在尝试让 <Redirect> 子组件在状态改变时重新渲染,特别是调用 setUserInSystem 时,它应该更新 userInSystem ,这在渲染方法中被显式引用。然而,当 userInSystem 改变时,组件并没有重新渲染,我无法找出原因。(注意:两个异步函数 getUserInfogetUserByWorkEmail 正如预期一样工作,并检索正确的数据。)
const App = (props) => {
  const { authState, authData } = props;
  const [signedIn, setSignedIn] = useState(false);
  const [userInfo, setUserInfo] = useState(undefined);
  const [userInSystem, setUserInSystem] = useState(false);

  useEffect(() => {
    setSignedIn(!(authState !== 'signedIn'));
    const fetchUser = async () => {
      const data = await getUserInfo();
      const userFound = await getUserByWorkEmail(data);
      setUserInSystem(userFound);
      setUserInfo(data);
    };
    if (authState === 'signedIn') {
      fetchUser();
    }
  }, [authState]);


return (
    <div>
        <BrowserRouter>
            <Switch>
            <Redirect
                exact={true}
                path="/"
                to={userInSystem ? '/dashboard' : '/unverified'}
            />
            </Switch>
        </BrowserRouter>
      </LayoutProvider>
    </div>
  );
};
2个回答

2
创建一个新的钩子,并在每次获取时更改条件,然后用该条件包装重定向。"最初的回答"
const [loading, setLoading] = useState(true);

在获取(fetch)完成后,将setLoading设置为false。
const fetchUser = async () => {
      setLoading(true);
      const data = await getUserInfo();
      const userFound = await getUserByWorkEmail(data);
      setUserInSystem(userFound);
      setUserInfo(data);
      setLoading(false);
    };

最初的回答
接着在返回值中:
<Switch>
{ !loading ? <Redirect
            exact={true}
            path="/"
            to={userInSystem ? '/dashboard' : '/unverified'}
        /> 
        : <div>Loading....</div> 
}
</Switch>

你知道为什么 setUserInSystemsetUserInfo 不会导致重新渲染吗? - Jono
它必须使用Redirect组件,如果是普通组件,由于你设置了用于组件(userInSystem)的prop,它将重新渲染。但是,也许重定向或切换之间具有一些逻辑,以防止简单的重新渲染。@jQwierdy - Josep Vidal

0

尝试将 userInSystem 添加到 useEffect 依赖数组中。

useEffect(() => {
    setSignedIn(!(authState !== 'signedIn'));
    const fetchUser = async () => {
      const data = await getUserInfo();
      const userFound = await getUserByWorkEmail(data);
      setUserInSystem(userFound);
      setUserInfo(data);
    };
    if (authState === 'signedIn') {
      fetchUser();
    }
  }, [authState, ***userInSystem***]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接