Javascript 使用React和Redux钩子,为什么我的动作没有开火?
编辑:解决了!请看Javascript 使用React和Redux钩子,为什么我的动作没有开火?,javascript,reactjs,react-redux,react-hooks,Javascript,Reactjs,React Redux,React Hooks,编辑:解决了!请看 我希望我的Blog组件在每次浏览器请求其URL时(无论是通过链接还是刷新)启动fetchBlog操作创建者。我想用ReactuseffectHook和React-ReduxuseDispatch和useSelectorHook来完成。但是,我的操作仅在跟随链接到页面时触发;我不明白为什么,即使在读了几篇解释之后(比如) 代码如下: //所有正确导入的内容,否则VSC会对我大喊大叫 导出默认函数Blog(){ const dispatch=usedpatch(); //slug
我希望我的
Blog
组件在每次浏览器请求其URL时(无论是通过链接还是刷新)启动fetchBlog
操作创建者。我想用Reactuseffect
Hook和React-ReduxuseDispatch
和useSelector
Hook来完成。但是,我的操作仅在跟随链接到页面时触发;我不明白为什么,即使在读了几篇解释之后(比如)
代码如下:
//所有正确导入的内容,否则VSC会对我大喊大叫
导出默认函数Blog(){
const dispatch=usedpatch();
//slug在这里设置为useSelector,它始终有效
useffect(()=>{
调度(fetchBlog(slug))
},[slug,dispatch]);
const blog=useSelector((state)=>state.blogs[0]);
//return从blog常量呈现blog信息
//由于操作未触发,因此blog未定义,因为state.blogs是一个空数组
}
我知道,在刷新时,fetchBlog
不会启动,因为Redux DevTools以及我在那里放置了一个调试器。(并且后端日志不显示传入的请求。)action creator本身和reducer必须工作;如果没有,当通过链接访问时,页面将无法正确加载
编辑:我已确定useSelector
和useDispatch
不是问题的根本原因,因为将代码更改为使用connect
与MapStateTrops
和mapDispatchToProps
会产生相同的结果。问题似乎在于useffect
我不清楚slug来自何处。
理论上,useffect
在每次渲染后运行。如果有多个参数,当第二个参数中传递的数组参数之一发生更改时,它将运行回调
创建一个useffect
,将空数组作为第二个参数运行一次(例如刷新时),或者检查slug值
检查回购协议后的编辑:
- 它不会起作用,因为useEffect是在渲染之后运行的(虽然有人否决了它,但我的答案中包含了它)。分派调用只会在之后发生,或者如果在之前引发异常(在本例中为空指针),则根本不会发生李>
- 您可以使用
匹配
从react路由器获取slug,这可能很方便您了解
export default function Blog({ match }) {
const slug = match.params.slug;
etc
- git repo显示了如何将dispatch as作为数组参数添加到
useffect
,这是不必要的
我认为问题在于您正在将呼叫返回调度。从useEffect返回的函数是清理函数,所以我认为这不会在装载时运行,也不会只在卸载之前进行更新。试试这个:
导出默认函数Blog(){
// ...
//不要从useEffect返回。只需在体内调用dispatch。
useffect(()=>{
调度(fetchBlog,slug);
},[slug,dispatch]);
// ...
}
我想澄清问题所在,@Trace引导我找到了问题所在
刷新时未调用useffect
,因为它在组件呈现/返回后被调用。刷新时,状态(包括博客数据)丢失;不是返回,而是抛出TypeError
,因为data.title
不存在。因此useffect
永远不会被调用并获取博客的内容
解决方案如下:
导出默认函数Blog(){
// ...
useEffect(/*…*/)
const blog=useSelector((state)=>state.blogs[0]);
如果(!博客){
返回加载
}
//在这里返回实际的博客内容
}
因此,现在确实调用了fetchBlog
,更新blog
并呈现内容。组件是否已卸载,可能这就是它之后不启动的原因?我不认为它已卸载,因为我仍然会得到一个错误:操作未启动,因此状态。blogs
是一个空数组,因此数据
未定义,因此,阅读JSX部分中的blog.title
会引发一个TypeError:无法读取未定义的的属性'title'。但我对此不是很有信心-我怎么能100%肯定组件已卸载?有什么可能卸载它呢?我认为问题是,组件在使用新组件重新装载之前,可能并不总是卸载slug.So op希望保持第二个使用效果参数不变。@pizza-r0b我不知道为什么您要说卸载,因为用户清楚地谈到了页面刷新,这意味着所有组件都被重新加载。“无论是通过链接还是刷新”“但是,我的操作仅在链接到页面“+“我知道,刷新时,fetchBlog不会启动"感谢您的输入!我知道slug是正常的,我可以记录它,它显示正常。我更改了代码,使回调传递到useffect
两个调用fetchBlog
,并返回相同的调用。这样,在卸载时将调用返回值。这并不能解决问题。我还从t他删除了数组,并删除了数组本身,我得到的只是一个警告,它们丢失了。你说得对,我不应该从useffect
中返回,谢谢。不幸的是,这仍然不能解决问题-useffect
本身在刷新时不会被触发。尽管如此,我感谢你的支持put.@brunoparga尝试使用空数组运行它,即使它仍然不起作用,也可以排除通过useEffect数组传递的参数存在问题的可能性。这给了我第12:6行:React Hook useEffect缺少依赖项:“dispatch”和“slug”。包括它们或删除依赖项数组在屏幕上显示react hooks/deps