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

时间:2019-11-27 15:07:14

标签: javascript reactjs react-redux react-hooks

编辑:已解决!请参阅below

我希望我的Blog组件在浏览器每次通过链接或刷新请求URL时触发fetchBlog动作创建者。我想用React useEffect钩子和React-Redux useDispatchuseSelector钩子来做。但是,只有在点击该页面的链接时,我的操作才会触发;即使阅读了几个解释(例如the official docs),我也不明白为什么。

代码如下:

// Everything duly imported, or else VSC would yell at me

export 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。 (并且后端日志不显示请求传入。)动作创建者本身和减速器必须正在工作;如果不是,则通过链接访问该页面时将无法正确加载该页面。

编辑:我确定useSelectoruseDispatch不是问题的根本原因,因为将代码更改为将connectmapStateToProps和{{1}一起使用给出相同的结果。问题似乎出在mapDispatchToProps上。

3 个答案:

答案 0 :(得分:1)

我认为问题在于您正在退回呼叫以进行分派。从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

答案 1 :(得分:0)

我不清楚the的来源。
理论上,group$在每次渲染后运行。如果有多个参数,则当第二个参数中传递的数组参数之一发生更改时,它将运行回调。

要么创建一个source$ .pipe( groupBy(item => item.whatever), mergeMap(group$ => group$.pipe( throttleTime(1000) )), ) .subscribe(...); 并将空数组作为第二个参数,然后“一次”运行它(例如,刷新时),要么检查段塞值。

在检查仓库后进行编辑:

  • 这是行不通的,因为useEffect是在渲染之后运行的(虽然有人投票反对,但它包含在我的答案中)。仅在此异常之前(在这种情况下为null指针)之前抛出该调用,才分派该调用。
  • 您可以使用useEffect从react-router中获取该信息,可能对您有所帮助。

    useEffect
  • git仓库显示了如何将dispatch as作为数组参数添加到match,这是不必要的。

答案 2 :(得分:0)

我想弄清楚问题是什么,@ Trace指导我找到了这个问题。

刷新时未调用

useEffect是因为它在组件渲染/返回之后被称为 。刷新时,状态(包括博客数据)会丢失;而不是返回,而是抛出TypeError,因为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并呈现了内容。