问题所在
是什么警告呢?程序员与程序的斗争是这样的:
一小白在componetWillMount中访问了接口返回数据后,调用了setState,访问的时候按了后退,导致还没收到响应就销毁了组件 ,但是fetch请求没被结束掉,之后 收到响应就调用了setState(),发出警告。请问这种情况该怎么处理?在unmount中结束fetch吗?但fetch怎么结束呢?官方文档好像没有api。
JavaScript某大佬,小伙你还是太年轻,但你却又异于常人,看你骨骼惊奇,并非凡人,将来必成大业,不如这样,我这里有本JavaScript语言精粹,你拜我为师,我传授于你,等你练至大成之时,就是你纵横JavaScript之日!
各位大佬莫当真,上述只是为了放松放松各位大佬的心情。
如何解决?
前端工程师大佬:
正确的做法是不要在请求callback里setState,用不会被卸载的组件请求然后用props分发下来数据。
这也是为什么Redux或者Mobx流行的原因,只用React基本就要踩到这种坑,因为除了最顶层的组件,有几个组件是真的不会被卸载的呢?
如果实在没办法临时解决,只能加个this.isUnmount,在componentWillUnmount设置为true,然后在fetch callback里判断如果this.isUnmount不为true的时候再setState。
这里面还有cancellable promise的方法,不建议使用。最好将promise当作不可变的,这样心智模型比较简单。
fetch现在还不能取消?如果你在component life cycle里面进行异步操作会遇到setState warning!
自己封装一个cancelable Promise,在unmount的时候cancel掉。
对于通用数据抽到redux的store里用connect传props。
使用rxjs对异步做subscribe,unmount的时候dispose掉。
在异步setState之前做mount判断。
如果你确认这个异步setState没有侵入性,也可以不理它。warning的目的在于让开发者确认自己的编码存在潜在的问题,在prod下是不报的。
当然,这里说一下,各部分关于JavaScript/CSS/HTML5等等参考资料以及案例的小伙伴们可来我的前端群:621071874,这里有小编收集到的各部分资料以及案例,望能帮到各位。
前端工程师中的扛把子:
有个this.isMounted属性可以判断当前组件是否挂载,你可以在setState之前做一下判断。
这确实是个坑,但我觉得这本身也不是react应该负责的。合情合理,组件挂载的时候设置了什么,在卸载的时候最好清理一下,最常见的还有定时器。
异步请求发起后不能撤销的这个锅react不背~不过应该提供解决方案,判断isMounted再setState,就是一种解决方案。
用redux?
React的props vs state是一个大坑。
用了redux, 世界就清净了。组件根本不要再用state, 状态只依靠props。组件要改变状态,一律通过dispatch执行action, reducer改变store,redux再自动map store到组件的props.
用了redux, 你永远不需要call setState()
神解决
程序员为什么要在乎warning?(你这解决方案实在太牛逼,请允许我做个悲伤的表情↓)
2
不知道各位大佬看完最后一个解决方法是作何感想?