目录
只存储跟组件渲染相关的数据(比如count、列表数据、loading等)
注意:不用做页面渲染的数据不要放在state中(比如定时器、id等),可以放在this中
组件更新机制: 父组件更新会引起子组件也被更新(子组件没有任何变化也会重新渲染)
问:如何避免不必要的渲染?
答:用钩子函数shouldComponentUpdate解决(返回true重新渲染,返回false不重新渲染)
→ 该函数属于更新阶段的钩子函数,在组件重新渲染render前执行
完整代码
- import React from "react";
- import ReactDOM from "react-dom";
-
- class App extends React.Component {
- state = {
- count: 1
- }
- fn = () => {
-
- this.setState((state, props) => {
- return {
- count: state.count + 1
- }
- }, () => {
- console.log("更新的:" + this.state.count)
- })
-
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- //最新的状态
- console.log("nextState:",nextState)
- //更新前的状态
- console.log("this.state:",this.state)
- //返回false 阻止组件重新渲染
- return false;
- }
-
- render() {
- return (
- <div>
- <p>count:{this.state.count}p>
- <button onClick={this.fn}>点我button>
- div>)
- }
- }
-
-
- ReactDOM.render(<App/>, document.getElementById("root"));
效果
点击按钮3次,state里的count的最新值是4,因为使用了钩子函数shouldComponentUpdate, return 了 false, 所以不重新渲染页面, 所以页面上的count还是1 (备注:this.state里面的count值为3 是因为setState更新数据是异步的,所以count的最新值还没有更新过来)
把钩子函数shouldComponentUpdate的返回值改为true (允许组件重新渲染),点击按钮三次.页面的count值又恢复了
实现效果: 当两次生成的随机数不一样的时候才重新渲染页面
- import React from "react";
- import ReactDOM from "react-dom";
-
- class App extends React.Component {
- state = {
- number: 0
- }
- fn = () => {
-
- this.setState(() => {
- return {
- number:Math.floor(Math.random()*3)
- }
- })
-
- }
-
- shouldComponentUpdate(nextProps, nextState) {
- //最新的状态
- console.log("最新的状态:",nextState)
- //更新前的状态
- console.log("上一次的状态:",this.state)
-
- //当两次生成的随机数是一样的时候,不重新渲染页面
- // if(nextState.number===this.state.number){
- // return false;
- // }
- // return true;
-
- //当两次生成的随机数不一样的时候才重新渲染页面
- return nextState.number!==this.state.number
- }
-
- render() {
- console.log("render")
- return (
- <div>
- <p>随机数:{this.state.number}p>
- <button onClick={this.fn}>产生随机数button>
- div>)
- }
- }
-
-
- ReactDOM.render(<App/>, document.getElementById("root"));
效果
代码
- import React from "react";
- import ReactDOM from "react-dom";
-
- class App extends React.Component {
- state = {
- number: 0
- }
- fn = () => {
-
- this.setState(() => {
- return {
- number:Math.floor(Math.random()*3)
- }
- })
-
- }
-
-
- render() {
- console.log("父组件的render")
- return (
- <div>
- <Box number={this.state.number}/>
- <button onClick={this.fn}>产生随机数button>
- div>)
- }
- }
-
- class Box extends React.Component{
- shouldComponentUpdate(nextProps){
- console.log("最新的props:",nextProps,"上一次的props:",this.props)
- if(nextProps.number!==this.props.number){
- return true;
- }
- return false;
- }
- render(){
- console.log("子组件的render")
- return <p>随机数:{this.props.number}p>
- }
- }
-
- ReactDOM.render(<App/>, document.getElementById("root"));
效果
为什么要用纯组件?
纯组件内部自动实现了shouldComponentUpdate这个钩子函数,不需要手动比较
使用方法:继承 React.PureComponent
代码
- import React from "react";
- import ReactDOM from "react-dom";
-
- class App extends React.PureComponent {
- state = {
- number: 0
- }
- fn = () => {
-
- this.setState(() => {
- return {
- number:Math.floor(Math.random()*3)
- }
- })
-
- }
-
-
- render() {
- return (
- <div>
- <Box number={this.state.number}/>
- <button onClick={this.fn}>产生随机数button>
- div>)
- }
- }
-
- class Box extends React.PureComponent{
-
- render(){
- console.log("子组件的render")
- return <p>随机数:{this.props.number}p>
- }
- }
-
- ReactDOM.render(<App/>, document.getElementById("root"));