猿问

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

编辑:已解决!请看下文。


我希望我的组件在每次浏览器请求其 URL 时Blog触发动作创建者,无论是通过链接还是刷新。fetchBlog我想用 React useEffectHook 和 React-ReduxuseDispatch和useSelectorHooks 来做。但是,我的操作仅在点击页面链接时触发;我不明白为什么,即使在阅读了几个解释(如官方文档)之后。


这是代码:


// 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那里放了一个。(并且后端日志没有显示进来的请求。)动作创建者本身和reducer 必须在工作;如果不是,则通过链接访问该页面时将无法正确加载。


编辑:我已经确定useSelector并且useDispatch不是问题的根本原因,因为更改要使用的代码connect并mapStateToProps给出mapDispatchToProps相同的结果。问题似乎与useEffect.


qq_花开花谢_0
浏览 253回答 3
3回答

慕码人2483693

我认为问题是您正在返回调用调度。从 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

慕森卡

我想澄清问题是什么,@Trace 引导我找到了。useEffect没有在刷新时被调用,因为它在组件渲染/返回后被调用。刷新时,状态(包括博客数据)丢失;而不是返回,aTypeError被抛出,因为data.title不存在。所以useEffect永远不会有机会被调用并获取博客的内容。解决方案是这样的:export default function Blog() {&nbsp; // ...&nbsp; useEffect(/* ... */)&nbsp; const blog = useSelector((state) => state.blogs[0]);&nbsp; if (!blog) {&nbsp; &nbsp; return <p>Loading...</p>&nbsp; }&nbsp; // return actual blog contents here}&nbsp;&nbsp;所以现在fetchBlog确实被调用,更新blog和渲染内容。

慕尼黑5688855

我不清楚蛞蝓是从哪里来的。理论上useEffect在每次渲染后运行。如果有多个参数,它将在第二个参数中传递的数组参数之一发生更改时运行回调。要么创建一个useEffect空数组作为第二个参数以“一次”运行它(例如,当您刷新时)或检查 slug 值。检查回购后的编辑:它不起作用,因为 useEffect 在渲染之后运行(尽管有人反对它,但它包含在我的答案中)。如果之前抛出异常(在本例中为空指针),则调度调用只会在之后发生,或者根本不会发生。您可以从 react-router 获取 slug match,可能对您很方便。export default function Blog({ match }) {&nbsp; &nbsp; const slug = match.params.slug;etcgit repo 显示了如何将 dispatch as 作为数组参数添加到useEffect,这不是必需的。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答