Overview
近来常有进修React相干的手艺,写了几个React的小Demo,运用 React/Express
手艺栈。着实太小,羞于拿出来细说。React 的确是一个值得跟随的手艺。但React系统着实巨大,我现在仅略知一二。这里要挑出来说的,是React的性命周期机制。Demo的进修历程当中,对它的轻易、易用的地方着实是深有体会,在一些细节处也值得推敲,在这里做一下纪录,便于分享。
假如你打仗过React,也许对render
和componentWillMount
等,会相对的熟习,由于它们再经常使用不过。但用归用,个中的一些理论上的细节,每每轻易在运用的历程当中被疏忽,使我们多敲了不少代码,心很累的 : )
浅显来说,React 将组件 component
在web中的构成、修正和衬着等划分为多少个阶段,构成组件的性命周期。在一个完全的性命周期内,一个组件会经由多少个阶段,在迥殊的阶段组件会挪用一个迥殊的lifecycle method
,即性命周期要领。以下:
constructor(props)
componentWillMount()
render()
componentDidMount()
componentWillReceiveProps(nextProps)
shouldComponentUpdate(nextProps, nextState)
componentWillUpdate(nextProps, nextState)
render( )* //明白上与3. render()略有差别,见下。
componentDidUpdate(prevProps, prevState )
componentWillUnmount( )
值得注重,这些性命周期是React 内置的,在特定条件下就会被挪用。而开辟者能够做的就是
override
(重载)这些要领,以完成想要的功用。
constructor
constructor(props)
,组件构成时挪用。
constructor 函数可明白为组件的组织函数,从组件的类(class) 实例化一个组件实例。这个函数在组件构成时被挪用,是一切性命周期函数中最早实行
的。在constructor函数内,若有必要,举行state的初始化以及绑定要领;不然能够省去constructor函数的声明。
有以下几点在开辟时值得注重:
constructor 函数内,在实行任何statement之前,必需是super() 函数,假若有参数须将参数带上。这点跟Java很像。
在constructor 函数内,
this.props
返回undefined
不要在初试化state时援用props 里的值,不然每当props更新时,都须要在componentWillReceiveProps 函数内对state举行更新。(同时这也涉及到组件state拔取的准绳,若有须要请浏览Thinking in React)
class App extends Component {
constructor(props) {
super(props);//------------(1)
console.log(this.props);// undefined ------------(2)
//initialize the state
this.state = {
value: '',
color: props.initialColor // 不可取 ------------(3)
}
//bind methods
this.handleClick = this.handleClick.bind(this);
}
}
componentWillMount
componentWillMount()
,在组件初次衬着(render
)之前挪用。
mount
有装置
之意,我们能够明白为组件初次被加载在web中
。因而每次页面加载/革新,或许某个组件第一次加载进入web时能够挪用componentWillMount( ) 函数。举个例子,在初次进入文章列表常常,可在 componentWillMount 对一切文章举行查询。如许,在render之前,就可以拿到一切文章的数据,以便在render中运用。
在componentWillMount ( ) 函数内,若对
this.state
举行更新,没法触发从新衬着组件。
class PostList extends Component {
//...
//在componentWillMount 组件内猎取一切博客列表
componentWillMount(){
axios.get('/posts')
.then(res=>{
//...
});
}
//在 render 函数内将拿到的博客列表 衬着在页面中
render(){
//...
}
}
Render
render()
render 即 衬着函数,是编写组件代码时,唯一一个必需
的函数。该函数须有返回值,返回一个组件,即终究衬着出来的组件。在运用组件的class举行组件实例化时,获得的就是其返回值。
返回值有两种范例:
一个父标签,这个父标签内能够包括多少个子标签,在最外层标签必需只要一个。
false
或许null
,代表不衬着任何DOM
class App extends Component {
//...
render(){
return (
<div>
//...
</div>
)
}
}
注重:
在render函数中只做与返回组件相干的事情,勿在个中对state
举行操纵,能够保证每次挪用render函数,返回的组件都是雷同的。不然将加大项目保护本钱。别的,假如
shouldComponentUpdate
函数返回false
,则不实行render函数。关于shouldComponentUpdate将在下面引见。
componentDidMount
componentDidMount()
,一旦组件初次加载完成,便会挪用
假如须要对衬着出来的DOM节点做任何操纵,能够在此处举行。(提醒
: this.refs 可猎取实在DOM)。
在该组件内设置state将会致使组件被从新衬着。
class App extends Component {
//..
componentDidMount(){
//将会触发组件从新衬着
this.setState({
value: '100'
}):
//对节点举行操纵
this.refs.div.appendChild(newChild);
}
}
上面临 React性命周期函数
中的constructor
/ componentWillMount
/ render
/ componentDidMount
四个函数举行了引见。下面将继承引见别的5个要领。在此之前,先总结一下,下面列表中列出的3.render()
与8.render()
的在逻辑上的区分和联络。先上一个列表。
constructor(props)
componentWillMount( )
render( )
componentDidMount( )
componentWillReceiveProps(nextProps)
shouldComponentUpdate(nextProps, nextState)
componentWillUpdate(nextProps, nextState)
render()
*componentDidUpdate(prevProps, prevState)
componentWillUnmount()
「两个」render( )要领的区分
3.render( ) 与 8.render( )*
实质上,这两个要领毫无区分。但这里为何要说起它们之间的区分呢?实在,它们只是统一函数 render( ) 在组件性命周期的两个差别阶段的差别明白罢了。
前一个 render( ) 要领指在组件第一次被加载进入页面时,挪用的 render( ) 要领;后一个则指撤除第一次,以后挪用的 render( ) 要领。
因而,我们更情愿称第一次的 render( ) 要领为 mount
( 装置 ),称后一个 render( ) 要领为 re-render
( 从新衬着 ) 。这也是为何组件初次 render 前后的要领名中带有mount
一词的原因了。
这是 React 的手法,或许设想哲学吧。怎样以为都行,我以为很风趣?
下面引见的要领,都是缭绕第二个 render( ) ,即从新衬着 re-render 睁开的。
componentWillReceiveProps
componentWillReceiveProps(nextprops)
,已加载的组件
在 props 发作变化时挪用。
假如须要经由过程监听 props 的转变来修正 state 的值,则能够经由过程重载该函数完成。
须要注重
,在有些状况下,组件的 props 未发作转变也会挪用该函数。因而假如在该函数内的逻辑,只是想捕捉当前 props 与 吸收的 nextProps 的差别来做出一些操纵,则最好先将 props 与 nextProps 举行比较。
1.在
mounting
阶段,即初次 render ,不挪用 componentWillReceiveProps 要领。明白了两个 render( ) 的差别,便晓得这里是为何了。2.
this.setState({…})
不触发 componentWillReceiveProps 要领。由于该要领只监听 this.props 的转变,不关心 this.state 值的变化。
class App extends Component {
componentWillReceiveProps(nextProps){
//吸收的色彩 与 当前色彩差别时
if (this.props.color !== nextProps.color){
...
}
}
}
shouldComponentUpdate
shouldComponentUpdate(nextProps, nextState)
返回
true
orfalse
要不要更新(从新衬着)组件?浅显易懂。这个要领的返回值决议了,当 props 或许 state 值发作变化时,组件是不是从新衬着。两种状况:
返回
true
,从新衬着。紧接着,继承实行componentWillUpdate()
→render()
→componentDidUpdate()
。false
,不从新衬着。不再实行任何性命周期函数函数(亦不实行该组件的 render( ) 函数)。然则,并不阻碍其子组件。也就是说,假如其子组件的 props 或 state 发作转变时,只会取决于谁人组件的 shouleComponentUpdate ( ) 要领的返回值。原理虽懂,但碰到是可能会犯含糊,由于开辟中常常会碰见组件嵌套的状况,父子组件之间通报统一套 props 或 state,一来二去,谁更新谁不更新,轻易含糊,须要细致咯。
在绝大部分状况下,当 props 或 state 转变时,都是须要从新衬着组件的。
注重
,依据 React 官方 的说法,就算 shouldComponentUpdate( ) 要领返回false
,组件也会从新衬着。须要随时注重官方文档的变化。
class PostList extends Component {
shouldComponentUpdate(nextProps, nextState){
//return true;默许
return false;// 不更新组件
}
}
componentWillUpdate
componentWillUpdate(nextProps, nextState)
,当 shouldComponentUpdate( ) 要领返回 true 后挪用。
这个要领供应了一个为从新衬着作预备的时机,意义是要在这里,趁接下来的 render( ) 要领从新衬着之前,完成该完成的操纵。这个要领在 mount 阶段不会被挪用,只在 re-render 阶段被挪用。
注重
,不要在该要领内挪用this.setState({…})
,若有须要,请在 componentWillReceiveProps( ) 要领中完成。养成优越的编程范例。
class App extends Component {
componentWillUpdate(nextProps, nextState){
var isLate = this.nextProps.isLate;
if(isLate){
//...
} else {
//...
}
}
}
componentDidUpdate
componentDidUpdate(prevProps, preState)
,一旦组件初次更新(从新衬着)完成时挪用。
因而像 componentDidMount( ) 一样,假如须要对衬着出来的DOM节点做任何操纵,能够在此处举行。(提醒
: this.refs 可猎取实在DOM)。
在该组件内设置state将会致使组件被从新衬着。
class App extends Component {
//..
componentDidUpdate(){
//将会触发组件从新衬着
this.setState({
value: '100'
});
//对节点举行操纵
this.refs.div.appendChild(newChild);
}
}
componentWillUnmount
componentWillUnmount()
,在组件即将被卸载(或烧毁)之前挪用。
在这个要领中,适合做一些清算善后事情。比方清晰timer,作废收集要求,或许消灭在 componentDidMount 或 componentDidUpdate 中天生的相干 DOM 节点。
总结
mount
与re-render
的是有区分的。mount
阶段运用前一部分的四个要领( constructor / componentWillMount / render / componentDidMount),缭绕组件初次加载而挪用;后一部分
re-render
相干的,运用 componentWillReceiveProps / shouldComponentUpdate / componentWillUpdate / render / componentDidUpdate ,缭绕组件从新衬着而挪用。
我总结了一张流程图和一个表格,以示意这些周期函数之间的关联,以及在何种状况下会挪用这些函数。
注重:
componentWillUnmount 要领未包括个中。
mount | props 变化 | state 变化 |
---|---|---|
constructor | componentWillReceiveProps | shouldComponentUpdate |
componentWillMount | shouldComponentUpdate | (return true) ⏬ / 完毕 |
render | (return true) ⏬ / 完毕 | componentWillUpdate |
componentDidMount | componentWillUpdate | render |
/ | render | componentDidUpdate |
/ | componentDidUpdate | / |
完。
文章为本人原创,原文见本人个博:
浅析「React」性命周期(一)
浅析「React」性命周期(二)