指的是state或者props中数据是引用类型的情况下,在setState时候,必须改变最外层数据的引用,才能保证pureComponent能够重新render
原理
pureComponent中setState后,调用shouldComponentUpdate(nextProps,nextState,nextContext){shallowEqual(nextState, this.state)}
shouldComponentUpdate(nextProps,nextState,nextContext)
{
shallowEqual(nextState, this.state)
shallowEqual(nextProps, this.props)
}
demo
- 添加新书籍,数组添加一项
- 修改+1,数组项的count+1
粘贴代码,可忽略
import React, { PureComponent, Component } from 'react'
export class App extends PureComponent {
constructor() {
super()
this.state = {
message: 'hello world',
books: [
{
name: '你知不知道的js',
price: 99,
count: 1
},
{
name: '程序员之道',
price: 10,
count: 2
},
{
name: 'react深入浅出',
price: 88,
count: 20
},
{
name: 'vue深入浅出',
price: 9,
count: 4
}
]
}
}
addCount (index) {
console.log('index', index)
// this.state.books[index].count++
// this.setState({
// books: this.state.books
// })
const newBooks = [...this.state.books]
newBooks[index].count++
this.setState({
books: newBooks
})
}
addNewBook () {
const book = {
name: 'angular高级设计',
price: 9,
count: 4
}
// 直接修改state,重新设置,pureComponents无法更新
// this.state.books.push(book)
// const newBokks =
// this.setState({
// books: this.state.books
// })
const newBooks = [...this.state.books]
newBooks.push(book)
this.setState({
books: newBooks
})
}
// shouldComponentUpdate (nextProps, nextState) {
// shallowEqual(nextProps, this.props)
// shallowEqual(nextState, this.state)
// }
render () {
const { books } = this.state
return (
<div>
<h2>书籍列表</h2>
<ul>
{
books.map((item, index) => {
return (
<li key={item.name}>name:{item.name}-price: {item.price}-count: {item.count} <button onClick={() => this.addCount(index)}>+1</button></li>
)
})
}
</ul>
<button onClick={() => this.addNewBook()}>添加新书籍</button>
</div>
)
}
}
export default App
setState后不会变化
添加数据,这样不会变化,因为purComponent主要关注外层books是否是原来的
// push
this.state.books.push(newBook)
this.setState({
books: this.stae.books
})
//修改数组项
this.state.books[index].count++
this.setState({
books: this.state.books
})
setState后会变化
// push
const newBooks = [...this.state.books] //新的引用地址
newBooks.push(newBook)
this.setState({
books: newBooks
})
//修改数组项
const newBooks = [...this.state.books]
newBooks[index].count++
this.setState({
books: newBooks
})
总结
- state中引用类型必须浅拷贝一份,用拷贝之后的变量setState才可以让PureComponent render
- 数组前拷贝[...arr]