手动刷新页面时,如何强制 app.js 中的 useEffect 在其他组件的 useEffect 之前加载
How to force useEffect in app.js to load before other component's useEffect when refreshing page manually
我遇到了一些问题,似乎找不到解决问题的办法。问题是,当我手动输入时,假设您的目标是 localhost:3000/dashboard,它应该触发 app.js,这是我的根组件和仪表板组件。这里的问题是仪表板组件需要来自商店的用户,它只能在 app.js useEffect 挂钩中获得。为了简化这种方法,问题是仪表板 useEffect 在 app.js useEffect 之前触发,但我想以相反的方式进行,否则仪表板 useEffect 将 return undefined user from the store,但用户应该为 null 或 real用户名。
为了更好地理解,这里是我的简化代码:
App.js -> 在我的商店中设置用户并有路线
function App() {
const [{ user }, dispatch] = useStateValue();
useEffect(() =>{
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
dispatch({
type: 'SET_USER',
user: authUser
});
} else {
dispatch({
type: 'SET_USER',
user: null
});
}
});
return () => {
unsubscribe();
}
}, []);
console.log('User is >>>', user);
return (
<Router>
<div className="app">
<Switch>
<Route path="/dashboard">
<Dashboard />
</Route>
<Route path="/" >
<Header />
<Home />
</Route>
</Switch>
</div>
</Router>
);
##############################
Dashboard.js -> 应该从商店获取用户,以便它可以获取其他数据,但是由于用户未定义而发生错误,因为仪表板 useEffect 发生在 app.js useEffect
之前
const Dashboard = () => {
const [{user}] = useStateValue();
useEffect(() => {
console.log(`user is ${user}`);
getItemsByUser(user);
}, [])
const getItemsByUser = async (user) => {
const items = await firebaseService.getUserProducts(user);
console.log(items[0])
}
}
这里的主要问题是,当我手动刷新页面时,Dashboard useEffect 在 App.js useEffect 之前触发。如果我想导航到我的 header/navigation 中的 /dashboard 应该没问题,但我想涵盖手动方法。我该如何解决这个问题?..也许任何类型的中间件应该有所帮助,但我找不到任何有用的东西。
将您的效果编程为反应式。
useEffect(() => {
// This effect now handles all possible values of user.
// It will also update the Dashboard whenever the user state changes.
// This is the general approach because react state/context state
// value updates are asynchronous so consumers must
// handle undefined state.
if (user) getItemsByUser(user);
}, [user]);
顺便说一句,由于 React 的异步特性,从严格顺序的角度考虑解决方案通常没有帮助(比如试图让一件事先于另一件事发生)。相反,组件和挂钩中的逻辑应该只用于消耗可用的 props/state 并生成正确的 UI。即,它们应该是反应性的。当更新组件的某些依赖项时,效果只是声明哪些函数应该 运行 的一种简单方法。
我遇到了一些问题,似乎找不到解决问题的办法。问题是,当我手动输入时,假设您的目标是 localhost:3000/dashboard,它应该触发 app.js,这是我的根组件和仪表板组件。这里的问题是仪表板组件需要来自商店的用户,它只能在 app.js useEffect 挂钩中获得。为了简化这种方法,问题是仪表板 useEffect 在 app.js useEffect 之前触发,但我想以相反的方式进行,否则仪表板 useEffect 将 return undefined user from the store,但用户应该为 null 或 real用户名。
为了更好地理解,这里是我的简化代码:
App.js -> 在我的商店中设置用户并有路线
function App() {
const [{ user }, dispatch] = useStateValue();
useEffect(() =>{
const unsubscribe = auth.onAuthStateChanged((authUser) => {
if (authUser) {
dispatch({
type: 'SET_USER',
user: authUser
});
} else {
dispatch({
type: 'SET_USER',
user: null
});
}
});
return () => {
unsubscribe();
}
}, []);
console.log('User is >>>', user);
return (
<Router>
<div className="app">
<Switch>
<Route path="/dashboard">
<Dashboard />
</Route>
<Route path="/" >
<Header />
<Home />
</Route>
</Switch>
</div>
</Router>
);
##############################
Dashboard.js -> 应该从商店获取用户,以便它可以获取其他数据,但是由于用户未定义而发生错误,因为仪表板 useEffect 发生在 app.js useEffect
之前const Dashboard = () => {
const [{user}] = useStateValue();
useEffect(() => {
console.log(`user is ${user}`);
getItemsByUser(user);
}, [])
const getItemsByUser = async (user) => {
const items = await firebaseService.getUserProducts(user);
console.log(items[0])
}
}
这里的主要问题是,当我手动刷新页面时,Dashboard useEffect 在 App.js useEffect 之前触发。如果我想导航到我的 header/navigation 中的 /dashboard 应该没问题,但我想涵盖手动方法。我该如何解决这个问题?..也许任何类型的中间件应该有所帮助,但我找不到任何有用的东西。
将您的效果编程为反应式。
useEffect(() => {
// This effect now handles all possible values of user.
// It will also update the Dashboard whenever the user state changes.
// This is the general approach because react state/context state
// value updates are asynchronous so consumers must
// handle undefined state.
if (user) getItemsByUser(user);
}, [user]);
顺便说一句,由于 React 的异步特性,从严格顺序的角度考虑解决方案通常没有帮助(比如试图让一件事先于另一件事发生)。相反,组件和挂钩中的逻辑应该只用于消耗可用的 props/state 并生成正确的 UI。即,它们应该是反应性的。当更新组件的某些依赖项时,效果只是声明哪些函数应该 运行 的一种简单方法。