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

全文分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
})
}
保存看效果,貌似一切正常,组件按照需要的情况正常工作。感觉上好像是可行的解决方法,但其实并不是,这是错误而拙劣的手法。很明显这种方法是不受推荐的

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加载、页面初始化、有状态组件初始化、组件生命周期,有了更深的理解,算是有些收获。

 

react+dva 全局model中异步获取数据state在组件中取不到值的更多相关文章

  1. angular4,angular6 父组件异步获取数据传值子组件 undefined 问题

    通过输入和输出属性 实现数据在父子组件的交互在子组件内部使用@input接受父组件传入数据,使用@output传出数据到父组件详细标准讲解参考官方文档https://angular.cn/guide/ ...

  2. angular异步获取数据后在ngOnInit中无法获取,显示undefined解决办法

    两种方法 1 通过*ngif动态加载要数据渲染的dom 2 通过路由导航resolve 第一种感觉太麻烦了,要是一个页面请求多个接口,那就不得不写多个*ngif,本人还是更倾向与第二种发法 具体步骤: ...

  3. ajax异步获取数据后动态向表格中添加数据(行)

    因为某些原因,项目中突然需要做自己做个ajax异步获取数据后动态向表格中添加数据的页面,网上找了半天都没有 看到现成的,决定自己写个例子 1.HTML页面 <!doctype html> ...

  4. echarts异步数据加载(在下拉框选择事件中异步更新数据)

    接触echarts 大半年了,从不会到熟练也做过不少的图表,隔了一段时间没使用这玩意,好多东西真心容易忘了.在接触echarts这期间也没有总结什么东西,今天我就来总结一下如何在echart中异步加载 ...

  5. node 创建静态web服务器(下)(处理异步获取数据的两种方式)

    接上一章. 上一章我们说创建的静态web服务器只能识别html,css,js文件,功能较为单一,且图片格式为text/html,这是不合理的. 本章,我们将解决该问题. 这里,我们先准备好一个json ...

  6. datatables异步获取数据、简单实用

    IKC项目总结 一.认证难题管理模块 1. 如何使用datatables进行获取数据内容 datatables简介:Datatables是一款jquery表格插件.它是一个高度灵活的工具,可以将任何H ...

  7. 用redux-thunk异步获取数据

    概述 最近学习redux,打算用redux-thunk给todo添加异步获取数据组件.记录下来,供以后开发时参考,相信对其他人也有用. 注意: 在todo下方,我异步获取我的react博客的标题,点击 ...

  8. MVC—实现ajax+mvc异步获取数据

    之前写过ajax和一般处理程序的结合实现前后台的数据交换的博客,如今做系统用到了MVC,同一时候也用到了异步获取数据. ajax+一般处理程序与MVC+ajax原理是一样的在"URL&quo ...

  9. Vue Router路由守卫妙用:异步获取数据成功后再进行路由跳转并传递数据,失败则不进行跳转

    问题引入 试想这样一个业务场景: 在用户输入数据,点击提交按钮后,这时发起了ajax请求,如果请求成功, 则跳转到详情页面并展示详情数据,失败则不跳转到详情页面,只是在当前页面给出错误消息. 难点所在 ...

随机推荐

  1. VO(视图模型) 与 DTO(数据传输对象)的区别

    目录 VO(视图模型) 与 DTO(数据传输对象)的区别 1.VO与DTO概念 2.VO 视图模型的必要性与解耦 2.1 视图模型 2.2 视图模型存在的必要性 2.3 视图模型的解耦 3.DTO 存 ...

  2. 给spark submit main传递参数

    https://www.jianshu.com/p/1d41174441b6 注意传递过去的默认是string,如果修改只能在代码中修改

  3. Linux(Centos7)下redis5安装、部署、开机自启

    1.什么是redis redis是用C语言开发的一个开源的高性能键值对(key-value)数据库.它通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止redis支持的键值数据类型如下字符串 ...

  4. KubeSphere and Friends|12 月 14 日相约北京,不见不散

    如今在容器圈提到 Kubernetes,可谓是无人不知无人不晓.KubeSphere 作为一款面向云原生设计的开源项目,目的是在 Kubernetes 之上构建分布式多租户容器管理平台,提供简单易用的 ...

  5. 浅谈python中selenium库调动webdriver驱动浏览器的实现原理

    最近学web自动化时用到selenium库,感觉很神奇,遂琢磨了一下,写了点心得. 当我们输入以下三行代码并执行时,会发现新打开了一个浏览器窗口并访问了百度首页,然而这是怎么做到的呢? from se ...

  6. 第一个月.day1

    1. 编辑器下载 推荐的是hbulider     开发环境 2. 浏览器 推荐chrome 谷歌浏览器学习 3. 建立技术笔记 推荐博客园 Web 本月任务 搭建静态网页. 静态页面:不需要网络请求 ...

  7. linux命令-挂载命令

    一.挂载命令 1.mount 命令基本格式 linux 所有存储设备都必须挂载使用,包括硬盘 命令名称:mount 命令所在路径:/bin/mount 执行权限:所有用户 [root@localhos ...

  8. [WPF 自定义控件]使用WindowChrome自定义RibbonWindow

    1. 为什么要自定义RibbonWindow 自定义Window有可能是设计或功能上的要求,可以是非必要的,而自定义RibbonWindow则不一样: 如果程序使用了自定义样式的Window,为了统一 ...

  9. Customize the View Items Layout 自定义视图项目布局

    In this lesson, you will learn how to customize the default editor layout in a Detail View. For this ...

  10. Java 的 IO 流

    接着上一篇的 “Java 的 File 类” 的随笔,在File类的基础上,我们就走进Java的IO流吧. 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在 ...