我在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
在初始渲染后运行一样,useEffect
在初始渲染后执行,然后它的执行取决于是否将第二个参数(即依赖数组(传递给useEffect
钩子。
我应该使用其他什么解决方案?
您可以有条件地渲染内容,方法是确保在异步获取的数据可用后才渲染。
return (
{ auth ? <render content> : null}
);
或
return (
{ auth && <render content> }
);
p.S:语法中不包括尖括号< or >
。它们只是作为需要呈现的内容的占位符。
有关详细信息,请参阅:React-Conditional Rendering
可选
您可以使用useMemo
,它不需要等待re-render
。基于useEffect等依赖关系,它也将以同样的方式执行。
useMemo(()=>{
doSomething() //Doesn't want until render is completed
}, [dep1, dep2])