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

全文分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. POI解析Excel时,如何获取单元格样式以及单元格Style的一些操作

    最近,公司运营平台需要上传Excel文件并进行解析导入数据库,在开发完成后出现了一个始料不及的生产bug,下面是具体原因: 1.在用POI解析Excel时,默认如果Excel单元格中没有数据,且单元格 ...

  2. Filter Lookup Editor Data Source 筛选器查找编辑器数据源

    In this lesson, you will learn how to filter the data displayed by a lookup editor. This editor is s ...

  3. UI_DEV_Environment 之 StoryBook

    写在前面 由于本文主要集中关注与工具使用,所以不可能完全介绍工具的所有功能,所以要想了解更多,可以自己去各自官方网站上查看. github examples 什么是UI开发环境 UI开发环境专注于用户 ...

  4. JS基础语法---String(字符串的案例)

    练习1: var str = "我的宝宝最可爱,声音嗲嗲的"; var key = "可爱"; //先获取要截取的字符串的索引位置 var index = st ...

  5. SQL Server如何通过Page_ID找到对应的表

    其实本篇文章算是翻译Finding a table name from a page ID这篇文章,只是不想直接翻译.用自己的理解叙说出来.算是对上一篇博客"SQL Server如何找出一个 ...

  6. PHP—— 商品物流实时查询接口 (快递100API对接)

    PHP后台  与前端   对接商品物流信息的接口 运用的 快递100的API接口 public function getExpress() { $user_id = input('post.user_ ...

  7. [译]Vulkan教程(13)图形管道基础之Shader模块

    [译]Vulkan教程(13)图形管道基础之Shader模块 Shader modules Unlike earlier APIs, shader code in Vulkan has to be s ...

  8. java之可变个数的形参

    //采用数组形参来定义方法 public static void test (int a, String[] books); //采用可变个数形参来定义方法 public static void te ...

  9. Ubuntu16.04VIM无法补全错误记录

    先记录一下YouCompleteMe的安装过程. 按照教程进行安装 1. 安装 vundle # vundle是vim的包管理器,十分好用 cv@cv: ~$ git clone https://gi ...

  10. sublime插件开发教程4

    写几个简单的例子详解下 import sublime import sublime_plugin class ExampleCommand(sublime_plugin.TextCommand): d ...