前言
PureComponent通过浅比较props和state来防止页面不必要的渲染,本文是实验篇,通过React例子,以实验的方式验证PureComponent一些优化以及规避方式
实验
渲染过滤
PureComponent能阻止组件进行不必要的渲染
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div onClick={() => {
this.setState({
text: this.state.text + 1
})
}}>
<span>你好世界{this.state.text}</span>
<ChildComponent/>
</div>
)
}
}
class ChildComponent extends Component{
render() {
console.log('子组件输出')
return (
<div>
<span>这是一个子组件</span>
</div>
)
}
}
// 点击你好世界控制台会输出
// 父组件输出
// 子组件输出
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div onClick={() => {
this.setState({
text: this.state.text + 1
})
}}>
<span>你好世界{this.state.text}</span>
<ChildComponent/>
</div>
)
}
}
class ChildComponent extends PureComponent{
render() {
console.log('子组件输出')
return (
<div>
<span>这是一个子组件</span>
</div>
)
}
}
// 点击你好世界控制台会输出
// 父组件输出
地址更新触发渲染
如果组件的props和state中存在引用地址,引用地址中属性值的改变不会触发重新渲染,引用地址的改变才会触发重新渲染
import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
value: 0
}
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div
onClick={() => {
valueObj.value ++
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
<ChildComponent value={valueObj}/>
</div>
)
}
}
class ChildComponent extends Component{
render() {
console.log('子组件输出'+this.props.value.value)
return (
<div>
<span>这是一个子组件{this.props.value.value}</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台会输出
// 父组件输出
// 子组件输出1
import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
value: 0
}
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div
onClick={() => {
valueObj.value ++
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
<ChildComponent value={valueObj}/>
</div>
)
}
}
class ChildComponent extends PureComponent{
render() {
console.log('子组件输出'+this.props.value.value)
return (
<div>
<span>这是一个子组件{this.props.value.value}</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台会输出
// 父组件输出
import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
value: 0
}
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div
onClick={() => {
valueObj = {
value: 0
}
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
<ChildComponent value={valueObj}/>
</div>
)
}
}
class ChildComponent extends PureComponent{
render() {
console.log('子组件输出'+this.props.value.value)
return (
<div>
<span>这是一个子组件{this.props.value.value}</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出0
避免render中声明
render函数中声明对象会导致不必要的渲染
import React, {Component, PureComponent} from 'react';
import './App.css';
let valueObj = {
value: 0
}
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div
onClick={() => {
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
<ChildComponent value={valueObj}/>
</div>
)
}
}
class ChildComponent extends PureComponent{
render() {
console.log('子组件输出'+this.props.value.value)
return (
<div>
<span>这是一个子组件{this.props.value.value}</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div
onClick={() => {
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
<ChildComponent value={{value:0}}/>
</div>
)
}
}
class ChildComponent extends PureComponent{
render() {
console.log('子组件输出'+this.props.value.value)
return (
<div>
<span>这是一个子组件{this.props.value.value}</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出0
避免匿名函数
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
state = {
text: 0
}
render() {
console.log('父组件输出')
return (
<div>
<div
onClick={() => {
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
</div>
<ChildComponent onChildrenClick={(param) => {
console.log(param)
}}/>
</div>
)
}
}
class ChildComponent extends PureComponent {
onClickListen = () => {
this.props.onChildrenClick('这是参数')
}
render() {
console.log('子组件输出')
return (
<div onClick={this.onClickListen}>
<span>这是一个子组件</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出
// 点击这是一个子组件控制台输出
// 这是参数
import React, {Component, PureComponent} from 'react';
import './App.css';
class App extends Component {
state = {
text: 0
}
onChildrenClickListen = (param) => {
console.log(param)
}
render() {
console.log('父组件输出')
return (
<div>
<div
onClick={() => {
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
</div>
<ChildComponent onChildrenClick={this.onChildrenClickListen}/>
</div>
)
}
}
class ChildComponent extends PureComponent {
onClickListen = () => {
this.props.onChildrenClick('这是参数')
}
render() {
console.log('子组件输出')
return (
<div onClick={this.onClickListen}>
<span>这是一个子组件</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 点击这是一个自组件控制台输出
// 这是参数
map遇上回调函数
当render中组件时涉及map循环遍历,同时map中返回的内容需要绑定回调事件,那么将map中返回的内容单独抽离成组件可以激活筛选渲染
import React, {Component, PureComponent} from 'react';
import './App.css';
const dataArray = [1,2]
class App extends Component {
state = {
text: 0
}
onChildrenClickListen = (param) => {
console.log(param)
}
render() {
console.log('父组件输出')
return (
<div>
<div
onClick={() => {
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
</div>
{
dataArray.map((item, index) => {
return (
<ChildComponent onChildrenClick={() => {
this.onChildrenClickListen(item)
}}/>
)
})
}
</div>
)
}
}
class ChildComponent extends PureComponent {
render() {
console.log('子组件输出')
return (
<div onClick={this.props.onChildrenClick}>
<span>这是一个子组件</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 子组件输出
// 子组件输出
// 点击第一个这是一个子组件控制台输出
// 1
import React, {Component, PureComponent} from 'react';
import './App.css';
const dataArray = [1,2]
class MyMapItem extends PureComponent {
onChildrenClickListen = () => {
this.props.onChildrenClickListen(this.props.item)
}
render(){
return (
<ChildComponent onChildrenClick={this.onChildrenClickListen}/>
)
}
}
class App extends Component {
state = {
text: 0
}
onChildrenClickListen = (param) => {
console.log(param)
}
renderMap = (item, index) => {
return <MyMapItem item={item} onChildrenClickListen={this.onChildrenClickListen}/>
}
render() {
console.log('父组件输出')
return (
<div>
<div
onClick={() => {
this.setState({
text: this.state.text + 1
})
}}
>
<span>你好世界{this.state.text}</span>
</div>
{
dataArray.map(this.renderMap)
}
</div>
)
}
}
class ChildComponent extends PureComponent {
render() {
console.log('子组件输出')
return (
<div onClick={this.props.onChildrenClick}>
<span>这是一个子组件</span>
</div>
)
}
}
export default App;
// 点击你好世界控制台输出
// 父组件输出
// 点击第一个这是一个子组件控制台输出
// 1