3 回答
TA贡献1860条经验 获得超9个赞
我认为问题是您正在返回调用调度。从 useEffect 返回的函数是清理函数,所以我认为这不会在挂载或更新时运行 - 仅在卸载之前运行。试试这个:
export default function Blog() {
// ...
// Don't return from useEffect. Just call dispatch within the body.
useEffect(() => {
dispatch(fetchBlog(slug);
}, [slug, dispatch]);
// ...
}
https://reactjs.org/docs/hooks-reference.html#cleaning-up-an-effect
TA贡献1806条经验 获得超8个赞
我想澄清问题是什么,@Trace 引导我找到了。
useEffect没有在刷新时被调用,因为它在组件渲染/返回后被调用。刷新时,状态(包括博客数据)丢失;而不是返回,aTypeError被抛出,因为data.title不存在。所以useEffect永远不会有机会被调用并获取博客的内容。
解决方案是这样的:
export default function Blog() {
// ...
useEffect(/* ... */)
const blog = useSelector((state) => state.blogs[0]);
if (!blog) {
return <p>Loading...</p>
}
// return actual blog contents here
}
所以现在fetchBlog确实被调用,更新blog和渲染内容。
TA贡献1848条经验 获得超2个赞
我不清楚蛞蝓是从哪里来的。
理论上useEffect在每次渲染后运行。如果有多个参数,它将在第二个参数中传递的数组参数之一发生更改时运行回调。
要么创建一个useEffect空数组作为第二个参数以“一次”运行它(例如,当您刷新时)或检查 slug 值。
检查回购后的编辑:
它不起作用,因为 useEffect 在渲染之后运行(尽管有人反对它,但它包含在我的答案中)。如果之前抛出异常(在本例中为空指针),则调度调用只会在之后发生,或者根本不会发生。
您可以从 react-router 获取 slug match,可能对您很方便。
export default function Blog({ match }) {
const slug = match.params.slug;
etc
git repo 显示了如何将 dispatch as 作为数组参数添加到useEffect,这不是必需的。
添加回答
举报