为了账号安全,请及时绑定邮箱和手机立即绑定

使用 React 和 Redux Hooks,为什么我的操作没有触发?

使用 React 和 Redux Hooks,为什么我的操作没有触发?

qq_花开花谢_0 2022-01-13 15:47:52
编辑:已解决!请看下文。我希望我的组件在每次浏览器请求其 URL 时Blog触发动作创建者,无论是通过链接还是刷新。fetchBlog我想用 React useEffectHook 和 React-ReduxuseDispatch和useSelectorHooks 来做。但是,我的操作仅在点击页面链接时触发;我不明白为什么,即使在阅读了几个解释(如官方文档)之后。这是代码:// Everything duly imported, or else VSC would yell at meexport default function Blog() {  const dispatch = useDispatch();    // slug is set here with useSelector, this always works  useEffect(() => {    dispatch(fetchBlog(slug))  }, [slug, dispatch]);  const blog = useSelector((state) => state.blogs[0]);    // return renders the blog information from the blog constant    // since the action does not fire, blog is undefined because state.blogs is an empty array}我知道,刷新时fetchBlog不会因为 Redux DevTools 而触发,也因为我在debugger那里放了一个。(并且后端日志没有显示进来的请求。)动作创建者本身和reducer 必须在工作;如果不是,则通过链接访问该页面时将无法正确加载。编辑:我已经确定useSelector并且useDispatch不是问题的根本原因,因为更改要使用的代码connect并mapStateToProps给出mapDispatchToProps相同的结果。问题似乎与useEffect.
查看完整描述

3 回答

?
慕码人2483693

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


查看完整回答
反对 回复 2022-01-13
?
慕森卡

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和渲染内容。


查看完整回答
反对 回复 2022-01-13
?
慕尼黑5688855

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,这不是必需的。


查看完整回答
反对 回复 2022-01-13
  • 3 回答
  • 0 关注
  • 252 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信