英文:
React Redux does not have time to work on first render because of useEffect
问题
I take a name from the path and give it to useeffect->dispatch and if array empty navigate to='', if not empty must show array. Navigate always works on the first render, the second time work normally. I'm trying to change useEffect to useLayoutEffect, but it also works on the first render.
file
const { car } = useParams();
const { carArray } = useSelector(state => state.carStore);
useEffect(() => {
dispatch(getCar(JSON.stringify(car)))
}, [car])
return (
<div>
{!carArray ? <Navigate to={"/"} /> : carArray.map..}
</div>
)
api
export const getCar = createAsyncThunk(
'get/car',
async (str) => {
const response = await axios.post("", str)
.then((r) => {
return r.data
})
.catch((err) => {
console.log(err)
})
return response
}
)
slice
builder.addCase(getCar.fulfilled, (state, action) => {
state.carArray = action.payload
})
console.log works like this
英文:
I take a name from the path and give it to useeffect->dispatch and if array empty navigate to='', if not empty must show array. Navigate always works on the first render, the second time work normally. I'm trying to change useEffect to useLayoutEffect, but it also works on the first render.
file
const { car } = useParams();
const { carArray } = useSelector(state => state.carStore);
useEffect(() => {
dispatch(getCar(JSON.stringify(car)))
}, [car])
return (<div>
{!carArray ? <Navigate to={"/"} : carArray.map..}
</div>)
api
export const getCar = createAsyncThunk(
'get/car',
async (str) => {
const response = await axios.post("", str)
.then((r) => {
return r.data
})
.catch((err) => {
console.log(err)
})
return response
}
)
slice
builder.addCase(getCar.fulfilled, (state, action) => {
state.carArray = action.payload
})
console.log works like this
答案1
得分: 2
这是因为返回JSX总是发生在useEffect
之前,一个解决方案是创建一个状态来处理“加载”阶段(第一次渲染):
const [loading, setLoading] = useState(true);
//...
useEffect(() => {
dispatch(getCar(JSON.stringify(car)));
setLoading(false);
}, [car]);
//...
if (loading) {
return <div>加载中...</div>;
} else {
return (
<div>
{!carArray ? <Navigate to={"/"} : carArray.map..}
</div>
)
}
如果你的目标是在第一次渲染期间获取数据,那么useEffect
不是正确的方法,它在第一次渲染之后运行,所以明显Redux状态仍然是一个空数组。你提到了useLayoutEffect
,但它不会帮助你实现你想要的效果,唯一的方法是在组件挂载之前提前调度getCar
动作,获取要传递给该函数的ID不会成为问题。
英文:
This is because returning JSX always happens before useEffect
, one solution is to create a state to handle the "loading" phase (the first render):
const [loading, setLoading] = useState(true);
//...
useEffect(() => {
dispatch(getCar(JSON.stringify(car)));
setLoading(false);
}, [car]);
//...
if (loading) {
return <div>Loading...</div>;
} else {
return (<div>
{!carArray ? <Navigate to={"/"} : carArray.map..}
</div>)
}
If your goal is to get the data during the first render, then useEffect
is not the right way to go,it runs after the first render so it is abvious that the redux state is still an empty array then.<br>
You have mentionned useLayoutEffect
but it will not help achieving what you want, the only way is to dispatch getCar
action earlier, before the component mounts, geting the id to pass to the function won't be a problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论