扫码关注官方订阅号
根据文档说法,从后台获取数据一定要放在componentDidMount里面调用,为什么不能在constructor或者componentWillMount里面调用?有什么不同?
ringa_lee
这与React组件的生命周期有关,组件挂载时有关的生命周期有以下几个:
constructor()
componentWillMount()
render()
componentDidMount()
上面这些方法的调用是有次序的,由上而下,也就是当说如果你要获取外部数据并加载到组件上,只能在组件"已经"挂载到真实的网页上才能作这事情,其它情况你是加载不到组件的。
componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。
constructor被调用是在组件准备要挂载的最一开始,所以此时组件尚未挂载到网页上。
componentWillMount方法的调用在constructor之后,在render之前,在这方法里的代码调用setState方法不会触发重渲染,所以它一般不会用来作加载数据之用,它也很少被使用到。
一般的从后台(服务器)获取的数据,都会与组件上要用的数据加载有关,所以都在componentDidMount方法里面作。虽然与组件上的数据无关的加载,也可以在constructor里作,但constructor是作组件state初绐化工作,并不是设计来作加载数据这工作的,所以所有有副作用的代码都会集中在componentDidMount方法里。
补充一下,Redux作初始数据载入时,是可以不需透过React组件的生命周期方法,大致的方式如下代码:
import React from 'react' import ReactDOM from 'react-dom' import { createStore } from 'redux' import { Provider } from 'react-redux' import App from './App' // reducer function items(state = [], action) { switch (action.type) { case 'LOAD_ITEMS': return [...action.payload] default: return state } } // 创建store const store = createStore(items) fetch('http://localhost:8888/items', { method: 'GET' }) .then((response) => { // ok代表状态码在200-299 if (!response.ok) throw new Error(response.statusText) return response.json() }) .then((itemList) => { // 作dispatch动作,载入外部数据完成之后 store.dispatch({ type: 'LOAD_ITEMS', payload: itemList }) }) .catch((error) => { throw new Error(error.message) }) // React组件加载到真实DOM上 ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root'))
为何可以这样作的原因,是Redux的store中的状态有一个最初始的值(reducer上传参里的默认值),组件先初始化完成,接著异步的fetch用promise语法,在作完外部数据加载后,发送动作出来,此时reducer更动store里的状态,react-redux绑定器会触发React组件的重渲染,所以组件上数据会自动更新。
有问题再问吧,代码写得简略但测试过是可执行的。
constructor()中获取数据的话,如果时间太长,或者出错,组件就渲染不出来,你整个页面都没法渲染了。componentDidMount()中能保证你的组件已经正确渲染。
1、通常我在componentWillMount发送ajax(渲染dom之前做的操作)
2、componentDidMount也可以做ajax操作(渲染dom完成之后做的操作)
那么,这2种情况如何区分呢?
需求1:
当你的render函数需要有数据才能渲染的时候,就在componentWillMount做操作。
render() { return data && <p>{data}</p> }
需求2:
当你的render不需要数据,先渲染dom结构,就在componentDidMount操作。
render() { const { data } = this.props return ( <p> <span>我要先渲染</span> <span>{data || ''}</span> </p> ) }
你既然了解的周期的顺序,那就很好理解了啊!willMount在dom没有渲染前先进行的方法,如果这个时候请求ajax那么势必会有等待的这一刻,然后排队渲染dom,而didMount是在dom加载后在进行的方法,而这个时候请求ajax前面没有任何等待,直接请求,然后如果你setState那么整个虚拟dom会在此渲染,此时再将获得的数据进行渲染,这样就感觉很顺的就执行下去了。而再次渲染的同时大部分的dom都是没有改变的,只有部分改变,所以渲染的速度会很快
willMount
ajax
didMount
setState
虚拟dom
因为有很多前置工作要做
感谢各位的回答:总结一下不建议在constructor和componentWillMount里写的原因是
会阻碍组件的实例化,阻碍组件的渲染
如果用setState,在componentWillMount里面触发setState不会重新渲染
而在React Redux中,由于触发的渲染方式不同,是可以不需透过React组件的生命周期方法,所以我感觉可以在生命周期的任何地方调用。当然,在consttructor和componentWillMount还是会阻碍一点点组件的实例化和渲染。
是可以不需透过React组件的生命周期方法
由于@eyesofkids写的全面一点,我采纳他的了。
微信扫码关注PHP中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
这与React组件的生命周期有关,组件挂载时有关的生命周期有以下几个:
constructor()
componentWillMount()
render()
componentDidMount()
上面这些方法的调用是有次序的,由上而下,也就是当说如果你要获取外部数据并加载到组件上,只能在组件"已经"挂载到真实的网页上才能作这事情,其它情况你是加载不到组件的。
componentDidMount方法中的代码,是在组件已经完全挂载到网页上才会调用被执行,所以可以保证数据的加载。此外,在这方法中调用setState方法,会触发重渲染。所以,官方设计这个方法就是用来加载外部数据用的,或处理其他的副作用代码。
constructor被调用是在组件准备要挂载的最一开始,所以此时组件尚未挂载到网页上。
componentWillMount方法的调用在constructor之后,在render之前,在这方法里的代码调用setState方法不会触发重渲染,所以它一般不会用来作加载数据之用,它也很少被使用到。
一般的从后台(服务器)获取的数据,都会与组件上要用的数据加载有关,所以都在componentDidMount方法里面作。虽然与组件上的数据无关的加载,也可以在constructor里作,但constructor是作组件state初绐化工作,并不是设计来作加载数据这工作的,所以所有有副作用的代码都会集中在componentDidMount方法里。
补充一下,Redux作初始数据载入时,是可以不需透过React组件的生命周期方法,大致的方式如下代码:
为何可以这样作的原因,是Redux的store中的状态有一个最初始的值(reducer上传参里的默认值),组件先初始化完成,接著异步的fetch用promise语法,在作完外部数据加载后,发送动作出来,此时reducer更动store里的状态,react-redux绑定器会触发React组件的重渲染,所以组件上数据会自动更新。
有问题再问吧,代码写得简略但测试过是可执行的。
constructor()中获取数据的话,如果时间太长,或者出错,组件就渲染不出来,你整个页面都没法渲染了。
componentDidMount()中能保证你的组件已经正确渲染。
1、通常我在componentWillMount发送ajax(渲染dom之前做的操作)
2、componentDidMount也可以做ajax操作(渲染dom完成之后做的操作)
那么,这2种情况如何区分呢?
需求1:
需求2:
你既然了解的周期的顺序,那就很好理解了啊!
willMount在dom没有渲染前先进行的方法,如果这个时候请求ajax那么势必会有等待的这一刻,然后排队渲染dom,而didMount是在dom加载后在进行的方法,而这个时候请求ajax前面没有任何等待,直接请求,然后如果你setState那么整个虚拟dom会在此渲染,此时再将获得的数据进行渲染,这样就感觉很顺的就执行下去了。而再次渲染的同时大部分的dom都是没有改变的,只有部分改变,所以渲染的速度会很快因为有很多前置工作要做
感谢各位的回答:
总结一下不建议在constructor和componentWillMount里写的原因是
会阻碍组件的实例化,阻碍组件的渲染
如果用setState,在componentWillMount里面触发setState不会重新渲染
而在React Redux中,由于触发的渲染方式不同,
是可以不需透过React组件的生命周期方法,所以我感觉可以在生命周期的任何地方调用。当然,在consttructor和componentWillMount还是会阻碍一点点组件的实例化和渲染。由于@eyesofkids写的全面一点,我采纳他的了。