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

全文分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. 对python函数后面有多个括号的理解?

    一般而言,函数后面只有一个括号.如果看见括号后还有一个括号,说明第一个函数返回了一个函数,如果后面还有括号,说明前面那个也返回了一个函数.以此类推. 比如fun()() def fun(): prin ...

  2. Ligg.EasyWinApp-10300-Ligg.EasyWinForm:View的配置

    View的配置文件,  路径如下: .\Applications\xxxx(Apllication)\Clients\Form\Functions\yyyy(Function)\ Views\zzzz ...

  3. Navicat远程连接MySQL8,必知防坑策略

    项目上线是每一个开发工程师面临收获前面抓紧时间开发的成果,但有时我们上线项目首先需要做一些相关的业务测试.通过Xshell远程连接后使用命令行的方式连接操作Mysql这个没什么太大的你问题.但每次通过 ...

  4. vue-preview vue图片预览插件+缩略图样式

    一.安装 npm i vue-preview -S 二.main.js中  导入组件 //vue-preview 开始 import VuePreview from 'vue-preview'; // ...

  5. QGIS练手 - 标注

    又熬夜了... QGIS的标注就是标签,在QGIS3.x中有了改进. 不得不说,就光速度这一项,就能把ArcMap按在地上摩擦,更别说各种高级的标注样式了——除了标注功能面板UI有点“缺审美化”就是了 ...

  6. library: Vulnhub Walkthrough

    网络主机探测: 端口主机扫描: ╰─ nmap -p1-65535 -sV -A -O -sT 10.10.202.136 21/tcp open ftp vsftpd 3.0.380/tcp ope ...

  7. 卡拉OK歌词原理和实现高仿Android网易云音乐

    大家好,我们是爱学啊,继上一篇讲解了[LRC歌词原理和实现高仿Android网易云音乐],今天给大家带来一篇关于卡拉OK歌词原理和在Android上如何实现歌词逐字滚动的效果,本文来自[Android ...

  8. Chrome 开发者工具实用操作

    Chrome 开发者工具实用操作 https://umaar.com/dev-tips/

  9. 阿里云ECS服务器部署HADOOP集群(七):Sqoop 安装

    本篇将在 阿里云ECS服务器部署HADOOP集群(一):Hadoop完全分布式集群环境搭建 阿里云ECS服务器部署HADOOP集群(二):HBase完全分布式集群搭建(使用外置ZooKeeper) 阿 ...

  10. gitlab-CI作业-yml

    stages: - build - deploy before_script: - echo "Restore NuGet Packages..." - echo "do ...