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

Fil*_*lip 4 javascript reactjs redux react-redux react-hooks

我在 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>
  );
}
Run Code Online (Sandbox Code Playgroud)
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
    });
  }
};

Run Code Online (Sandbox Code Playgroud)

You*_*saf 5

我需要 useEffect 在渲染任何内容之前运行。我怎么能这么做呢?

您无法在初始渲染之前useEffect运行。

就像componentDidMount类组件在初始渲染之后运行一样,在初始渲染之后useEffect运行,然后其执行取决于是否传递第二个参数,即要挂钩的依赖数组。useEffect

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

您可以有条件地呈现内容,方法是确保在异步获取的数据可用后才呈现该数据。

return (
   { auth ? <render content> : null}
);
Run Code Online (Sandbox Code Playgroud)

或者

return (
   { auth && <render content> }
);
Run Code Online (Sandbox Code Playgroud)

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

详情请参见:React - 条件渲染