V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
devwolf
V2EX  ›  React

[提问] 关于 componentWillUnmount 里 this.setState = (state,callback)=>{ return;};起到的实际效果?直接使用 redux 时发生的问题

  •  2
     
  •   devwolf ·
    yctjb1 · 2019-09-09 10:46:59 +08:00 · 3862 次点击
    这是一个创建于 1662 天前的主题,其中的信息可能已经有所发展或是发生改变。
    this.setState = (state,callback)=>{ return;};也就是现在的 this.setState=({},()=>{return;});吧(成功的消错运行了)
    解决方法来自 https://stackoverflow.com/questions/53786551/reactjs-redux-cant-perform-a-react-state-update-on-an-unmounted-component
    现在我想请教各位大佬这样处理为什么能解决这个报错
    6 条回复    2019-09-09 14:47:12 +08:00
    devwolf
        1
    devwolf  
    OP
       2019-09-09 11:09:39 +08:00
    [在线再现报错]
    https://stackblitz.com/edit/redux-learn-01 这个是更小的例子展现了问题,可以在线编辑的 react+redux 项目。
    具体操作:
    pages/home/testone/index 中移除 componentWillUnmount 部分的处理,然后右侧点击测试 1->点击返回首页->点击测试 1->执行输入可以再现报错。
    momocraft
        2
    momocraft  
       2019-09-09 11:14:19 +08:00   ❤️ 1
    就是... 重寫了 setState 讓 react 不能發現你做了不該做的事

    > Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.

    報錯信息沒了不等於 "解決" 了, 至少錯誤信息讀一遍
    devwolf
        3
    devwolf  
    OP
       2019-09-09 11:36:59 +08:00
    @momocraft 大佬能再指点一下 1 楼的那个在线编辑项目里面是哪边引起了这个问题呢?
    momocraft
        4
    momocraft  
       2019-09-09 11:44:24 +08:00   ❤️ 1
    不知道也不太想替你 debug

    你试试给重写的 setState 加断点看看
    devwolf
        5
    devwolf  
    OP
       2019-09-09 13:43:52 +08:00
    感谢提示,如今我认为我遇到的问题已经解决(不包括诞生的问题)——
    在后续的排查出错原因中,找到了对这种处理的描述“重新定义 setState 方法来取消异步操作”:
    https://www.cnblogs.com/jlj9520/p/7371955.html 中对重写 setState 操作得到了确认,
    https://blog.csdn.net/GoldenLegs/article/details/86509806 一文提到了该处理是“阻止异步操作”,因为个人能力有限无法辨别该说法是否正确,故从 momocraft 的“報錯信息沒了不等於 "解決" 了”出发,继续寻找更稳妥的处理方法。
    https://www.jianshu.com/p/8be320d982a8 里的方法二中找到了,“设置一个 flag,当 unmount 的时候重置这个 flag”

    落实到楼一提到的迷你版 redux 项目里便是将 constructor 时 store.subscribe(this.handleStoreChange)订阅的 handleStoreChange 方法做一个组件是否卸载的判断 handleStoreChange(){
    if(this._isMounted === true){
    this.setState(store.getState())
    }
    }



    [说来惭愧也是技不如人] 原本在查到上述重写 setState 操作前有考虑过这个 flag 法子。
    不过我当时是在 export default 之上声明了个全局变量 flag 然后初次渲染时 true 卸载前 false,结果报错依旧。最后成功的处理里,这个 flag 是声明在组件的 this 上。
    有路过的好心人可以指出两者在此例中区别的话劳烦赐教一下,
    当然阁下如果没有雅兴那我只好寄望日后的学习里渐渐接触真相了 orz
    devwolf
        6
    devwolf  
    OP
       2019-09-09 14:47:12 +08:00
    题外话一下,
    题主因为今年毕业年挑毕设技术选用的的时候受了 vue+express+mongobd 这套安利(起个毕设用小项目还觉得挺便当的),所以面试的时候也就着 vue 指望在项目里深入一下来着(人菜瘾大)。结果刚进来就让转 react,开始的项目因为是别人架子用的 mirrorx 就没过多了解 redux,现在主管要求自己可以讲讲 mirrorx 简化了哪些实现,就自己淘宝了个视频回头看看 redux 和 react-redux。
    挺尴尬的,公司也是那种所谓后端即时全栈的地儿,只有洒家一个是冲着前端开发面试来着。进来的同期同事虽然一起在学 react,那些同事也就每天有余裕的时候看会儿 react,而题主就被丢在角落里扎猛子(想着题主会的他们都会,他们会的题主不会),忐忑不安地照领了夏天和中秋的员工福利。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2449 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 16:03 · PVG 00:03 · LAX 09:03 · JFK 12:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.