当this.setState()修改了state中的数据后,当前组件将重新渲染,同时也会重新渲染子组件,但只会渲染当前组件子树(当前组件以其所有子组件)
shouldComponentUpdate
当父组件更新会引起子组件也被更新,问题是此时子组件没有任何变化时也会重新渲染,我们就要避免不必要的重新渲染。解决方式使用钩子函数 shouldComponentUpdate(nextProps, nextState),这个函数有返回值,如果返回true,代表需要重新渲染,如果返回false,代表不需要重新渲染
在App.jsx组件中定义数据源,并设置修改
import React, { Component, createRef } from 'react' import Users from './components/Users';import Users2 from './components/Users2'; // 只有在类组件中才有生命周期 export default class App extends Component { state = { username: 'admin', sex: '男', count: 1 } componentDidMount() { setTimeout(() => { console.log('settimeout'); this.setState({ username: 'user' }) }, 3000); } render() { return ( <div> <Users username={this.state.username} /> <Users2 username={this.state.sex} /> </div> ) } }
子组件
在子组件中针对于props来完成有数据变化则进行组件渲染
本组件中state数据如果没有发现改变,则不发生渲染
import React, { Component} from 'react' // Component 类,不管是是否有数据更新,只要有数据变化,它和它的子组件都重新渲染
state = {
nickname: '就业榜'
}
export default class Users extends PureComponent {// 下一次的props和state数据 新数据 shouldComponentUpdate(nextProps, nextState) { // this.props.username 旧数据 if (nextProps.username === this.props.username && nextState.nickname === this.state.nickname) { // 当前的数据没有发生改变 return false } return true }
componentDidMount() {
setTimeout(() => {
console.log('就业榜');
this.setState({
nickname: '就业榜'
})
}, 3000);
}
render() { console.log('child-User----render'); return ( <div> 我是一个子组件 --- {this.props.username}
<hr />
<h3>{this.state.nickname}</h3>
</div>
)
}
}
PureComponent
React.PureComponent 与 React.Component 功能相似的,区别在于React.PureComponent 内部自动实现了 shouldComponentUpdate钩子,不需要手动进行比较操作。
原理:纯组件内部通过分别比对前后两次 props和state的值,来决定是否重新渲染组件
PureComponent它只是实现了浅层对比
- 对于值类型来说:比较两个值是否相同
- 引用类型:只比对对象的引用地址是否相同