繁体   English   中英

在渲染组件之前运行 useEffect 钩子

[英]Make useEffect hook run before rendering the component

我在我的 App.js 文件中使用了一个 useEffect 挂钩。 它将数据放入我需要在我的应用程序中使用的 redux 存储中。 但它在 useEffect 运行之前呈现,因此数据未定义。 然后 useEffect 正确运行。 我需要 useEffect 在任何东西被渲染之前运行。 我怎么能那样做? 或者我应该使用什么其他解决方案? 我曾尝试完全删除 useEffect 并仅运行该操作,但这会导致它无休止地运行。 这是我的代码:

function App() {
  const app = useSelector(state => state.app);
  const auth = useSelector(state => state.auth);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(authActions.checkUser());
  }, [dispatch]);

  console.log(auth.user); //undefined

  return (
    <ThemeProvider theme={!app.theme ? darkTheme : theme}>
      <CssBaseline />
      <React.Fragment>
        {/* TODO: Display drawer only when logged in */}
        {/* <Drawer></Drawer> */}
        <Switch>
          <Route exact path="/" component={Login} />
          <Route exact path="/dashboard">
            <Dashboard user={auth.user} /> //auth.user is undefined when this gets rendered
          </Route>
          <Route exact path="/register" component={Register} />
        </Switch>
      </React.Fragment>
    </ThemeProvider>
  );
}
export const checkUser = () => async dispatch => {
  let token = localStorage.getItem("auth-token");
  if (token === null) {
    localStorage.setItem("auth-token", "");
    token = "";
  }
  const tokenRes = await Axios.post("http://localhost:5000/users/tokenIsValid", null, {
    headers: { "x-auth-token": token }
  });
  if (tokenRes.data) {
    const userRes = await Axios.get("http://localhost:5000/users/", {
      headers: { "x-auth-token": token }
    });
    dispatch({
      type: CHECK_USER,
      token,
      user: userRes.data
    });
  }
};

我需要 useEffect 在渲染任何东西之前运行。 我怎么能那样做?

您不能在初始渲染之前运行useEffect

就像类componentDidMount中的 componentDidMount初始渲染useEffect运行一样, useEffect初始渲染之后运行,然后它的执行取决于您是否将第二个参数,即依赖数组传递给useEffect钩子。

我应该使用什么其他解决方案?

您可以通过确保在异步获取的数据可用后才对其进行渲染来有条件地渲染内容。

return (
   { auth ? <render content> : null}
);

或者

return (
   { auth && <render content> }
);

PS:尖括号< or >不包含在语法中。 它们只是作为您需要呈现的内容的占位符。

有关详细信息,请参阅: React - 条件渲染

选择

您可以使用useMemo ,它不等待re-render 它也将基于 useEffect 等依赖项以相同的方式执行。

useMemo(()=>{
    doSomething() //Doesn't want until render is completed 
}, [dep1, dep2])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM