文章目录
基础样例
新建react项目,主要包含以下文件:
- 模板文件index.html
- 入口文件index.js
- 入口组件App.js
- component/Demo/index.jsx、components/Demo/index.css,即Demo组件
模板文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PureComponent</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
入口文件index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";
ReactDOM.render(<App/>,document.getElementById("root"));
入口组件App.js
import React, { Component } from 'react'
import Demo from "./components/Demo"
export default class App extends Component {
render() {
return (
<div>
<Demo/>
</div>
)
}
}
Demo组件
Demo/index.css
.a{
width: 500px;
background: orange;
padding: 10px;
}
.b{
background: skyblue;
padding: 10px;
margin-top: 10px;
}
Demo/index.jsx
import React, { Component } from 'react'
import "./index.css";
export default class A extends Component {
state = {
username:"张三"
}
handleClick = () => {
this.setState({})
}
render() {
console.log("A:enter render()")
const {username} = this.state;
const {handleClick} = this;
return (
<div className="a">
<div>我是组件A</div>
<span>我的username是{username}</span>
<button onClick={handleClick}>执行setState且不改变状态数据</button>
<B/>
</div>
)
}
}
class B extends Component{
render(){
console.log("B:enter render()")
return (
<div className="b">
<div>我是组件B</div>
</div>
)
}
}
存在的问题
只要调用setState(),就会执行render(),即使state没有发生变化。
只要当前组件render,子组件会自动重新render,即使子组件的state或props都没有发生变化。
针对以上问题,下面将采取措施进行优化。
解决方案
涉及变更的文件有:component/Demo/index.jsx。
方案1:使用shouldComponentUpdate
import React, { Component } from 'react'
import "./index.css";
export default class A extends Component {
state = {
username:"张三"
}
handleClick = () => {
this.setState({})
}
shouldComponentUpdate(nextProps,nextState){
// console.log(this.props,this.state);
// console.log(nextProps,nextState);
return !(this.state.username === nextState.username);
}
render() {
console.log("A:enter render()")
const {username} = this.state;
const {handleClick} = this;
return (
<div className="a">
<div>我是组件A</div>
<span>我的username是{username}</span>
<button onClick={handleClick}>执行setState且不改变状态数据</button>
<B/>
</div>
)
}
}
class B extends Component{
render(){
console.log("B:enter render()")
return (
<div className="b">
<div>我是组件B</div>
</div>
)
}
}
shouldComponentUpdate()
是开关,只有当其返回值为true
时,组件render()才会执行。
方案2:使用PureComponent
PureComponent
帮我们做了shouldComponentUpdate
里该做的事情,所以我们可以偷懒了,可以不写shouldComponentUpdate
了。
import React, { PureComponent } from 'react'
import "./index.css";
export default class A extends PureComponent {
state = {
username:"张三"
}
handleClick = () => {
this.setState({})
}
render() {
console.log("A:enter render()")
const {username} = this.state;
const {handleClick} = this;
return (
<div className="a">
<div>我是组件A</div>
<span>我的username是{username}</span>
<button onClick={handleClick}>执行setState且不改变状态数据</button>
<B/>
</div>
)
}
}
class B extends PureComponent{
render(){
console.log("B:enter render()")
return (
<div className="b">
<div>我是组件B</div>
</div>
)
}
}
相关链接
【React】shouldComponentUpdate与React.PureComponent
react16:生命周期函数