• react+dva 全局model中异步获取数据state在组件中取不到值


    先上结论,不是取不到,是写法有问题。

    全文分4部分,1是问题描述,2是一开始的解决想法(错误做法),3是问题产生原因的思考,4是正常解决方法。只想看结论直接跳4

    1.问题描述

      接触react dva一个月,和同事都不算熟悉框架。在修改、使用同事的ui组件时,想用全局model保存的state来给组件state一个初始值,但组件中取不到登录后异步获取的用户信息。

      在组件constructor中取不到(仅有model state初始化的值,无异步获取的信息),但在组件使用时render中可以console出需要的值

    2.解决方法一(错误方法)
      由于render中可以获取到需要的值,所以第一反应是在这拿到需要的值,然后改变组件state给予组件初始值。
      但直接在render中使用setState很明显是会出错的,修改状态触发重新渲染,渲染中修改状态,又重渲染的死循环setState -> render -> setState -> render... ...
      所以加上了个条件如果state中没有值,才修改state
    if(!this.state.needData) {
      this.setState({
        needData: this.props.modelName.needData
      })
    }
    View Code
    保存看效果,貌似一切正常,组件按照需要的情况正常工作。感觉上好像是可行的解决方法,但其实并不是,这是错误而拙劣的手法。很明显这种方法是不受推荐的

    3.思考问题原因

      下班后思考问题原因。首先,根据props初始化组件state是符合操作逻辑的,不可能不支持;其次,组件中有时能取到,有时取不到。所以一定是我使用有问题,而且较大可以是在错误的时间使用了组件。

    那就需要定位问题所在,这时候console是个简单原始,但确实有效的帮手。

    把页面入口组件(0)问题组件constructor(1)问题组件render(2)model setup(3)异步数据获取到(4)分别加上console

    仔细看这个结果,也就不难得出结论了。

    组件constructor初始化组件在异步数据加载之前就已经完成,且数据加载以后,全局state修改触发的重新渲染并不会影响到constructor,其在组件生命周期里仅会执行一次。

    而查看该组件调用处发现,该组件是否显示(弹出组件,非一直显示)是把控制的flag传入了组件里,在组件内部控制是否显示。这种方式其实仅能控制组件内的元素是否显示,无法控制组件本身是否存在。正是这个原因,导致了组件在页面加载的之后便已经初始化完毕,之后仅控制显示与否。这其实不利于页面加载速度,也不符合按需加载的思想,还会导致异步数据初始化组件失败。所以我觉得不是个好的写法。

    那么也就有了第二种,我认为正确的解决方案

    4.解决方法二

    由3可以知道,组件在异步数据到来前已经完成初始化,是导致constructor中无法取到所需数据的原因。所以最直接的方法,就是修改组件创建的时间

    //把原来的组件内部控制显示
    /* <ComponentName show={modelName.show}/> */
    //更改为状态直接控制组件是否存在
    {
      modelName.show && <ComponentName/> 
    }
    //或者
    {
      modelName.show ? <ComponentName/> : null
    }
    
    //或者更严谨一点
    //由于项目中加入了用户数据获取失败,需重新登录,所以也就没有加上后面这个
    {
      modelName.show && modelName.needData && <ComponentName/> 
    }

    修改后

    目标组件不会在页面加载时就初始化

    而是在用户点击控制按钮,需要使用组件时,才初始化

    到此问题算是真正解决。

    由此问题,也让我对model加载、页面初始化、有状态组件初始化、组件生命周期,有了更深的理解,算是有些收获。

     
  • 相关阅读:
    水洼,八连杀
    友链
    万能转换字符类型到int ,int到string,string到char or char *等等
    蓝桥杯模拟赛题
    2020 03 21
    2019 12 02 reading
    CentOS 7 定时计划任务设置
    xinted &telnet
    2019 12 02 section C one
    【暖*墟】#洛谷网课1.30# 树上问题
  • 原文地址:https://www.cnblogs.com/liyan-web/p/9417599.html
Copyright © 2020-2023  润新知