结论:组件 render
的触发条件
- 首次加载组件
-
setState
改变组件内部的state
,父组件的state
改变也会触发子组件的render
- 接收的
props
发生改变
-
观察单个组件
setState
对组件render
的影响- 首先要明确组件的
setState
是会让组件执行render
的,并且因为React在开发环境中使用了严格模式(见下面代码),组件的constructor
和render
都各自执行了2遍,然后我们区分2种情况:(严格模式可参考 React 严格模式)- 在一个生命周期内同时执行2次
setState
- 在一个生命周期内,执行2次
setState
,第2次用setTimeout
延时执行
- 在一个生命周期内同时执行2次
- 从打印的结果图片可以看出,同时执行
setState
的,因为setState
而触发组件render
只会执行1次,因为react会将多次setState
排进队列里合并执行,也就是如果在setState
中多次累加同一个变量值但最后也只会执行1次;而延时执行setState
是会因此而继续触发render
的
- 首先要明确组件的
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// App.js
import React from 'react';
import './App.css';
class App extends React.Component {
constructor (props) {
console.log('App constructor')
super(props);
this.state = {
lifeProp: 'this is life prop',
list: []
}
}
// 1. 在一个组件中同时setState不同的2个变量
componentDidMount () {
this.setState({lifeProp: 'a new prop'})
this.setState({list: [1,2,3]})
}
// 2. 在一个组件中延时setState第2个变量
componentDidMount () {
this.setState({lifeProp: 'a new prop'})
setTimeout(() => {
this.setState({list: [1,2,3]})
}, 2000)
}
render () {
console.log('App render')
return (
<div className="App">
{/* 容器组件 */}
<CommentList></CommentList>
</div>
);
}
}
export default App;
一个组件中同时执行setState2次修改2个变量.jpg
一个组件延时修改第2个变量.jpg
-
观察父子组件
setState
对组件render
的影响- 首先使用最基本的父子组件配置,组件各自都只有基本的
constructor
、state
和render
,然后分别在组件中打印出各自的constructor
和render
的执行情况
- 首先使用最基本的父子组件配置,组件各自都只有基本的
// 父组件 App.js
import React from 'react';
import './App.css';
import {CommentList} from './components/CommentList'
class App extends React.Component {
constructor (props) {
console.log('App constructor')
super(props);
this.state = {
lifeProp: 'this is life prop',
list: []
}
}
render () {
console.log('App render')
return (
<div className="App">
{/* 容器组件 */}
<CommentList></CommentList>
</div>
)
}
}
export default App;
// 子组件 CommentList.js
import React from 'react'
export class CommentList extends React.Component {
constructor(props) {
console.log('CommentList constructor')
super(props)
this.state = {
comments: [],
tempData: '12345'
}
}
render () {
console.log('CommentList render')
return (
<div></div>
)
}
}
基本配置父子组件.jpg
- 再看第二种情况,由单个组件中
setState
对render
的影响我们可以推测出,当父组件setState
时,触发了父组件的render
,从而也触发子组件的render
,下面可以验证一下,下面是对组件的修改和结果:
// App.js
componentDidMount () {
this.setState({lifeProp: 'a new prop'})
setTimeout(() => {
this.setState({list: [1,2,3]})
}, 2000)
}
父组件setState对子组件的影响.jpg
- 第三种情况,我们了解下父组件向子组件传值的时候,父组件修改了传的值,对子组件的影响,本次修改结果同上
// App.js
componentDidMount () {
this.setState({lifeProp: 'a new prop'})
setTimeout(() => {
this.setState({list: [1,2,3]})
}, 2000)
}
// 将值传给子组件
<CommentList title={this.state.lifeProp}></CommentList>
// CommentList.js
// 在子组件接受父组件的传值
render () {
console.log('CommentList render')
return (
<div>
{this.props.title}
</div>
)
}
网友评论