forceUpdate()方法:
Sub.js
class Sub extends React.Component{
construcotr(){
super();
this.name = "yema";
}
refChangeName(name){
this.name = name;
this.forceUpdate();
}
render(){
return (<div>{this.name}</div>);
}
}
App.js
class App extends React.Component{
handleClick(){
this.subRef.refChangeName("yemafuren");
}
render(){
return (<div>
<Sub ref={(sub)=>{this.subRef = sub;}} />
<button onClick={this.handleClick}>click</button>
</div>);
}
} 复制代码
在Vue
中如果更改的data和上一次的data
相同,vue
便不会重新渲染,提高了性能。 但在react中才不管是不是相同,只要状态更新便会重新渲染,为此React提供了一个生命周期钩子函数
shouldComponentUpdate( )
这个钩子函数中接收最新的props
和state
但此时this
上的props
和state
还未更新,于是我们就可以做一下判断, 如果this.props === props
&&
this.state === state
则return false 代表此次不必要更新。否则return true
。(当我们没有写shouldComponentUpdate
时 React
底层默认return true
)
可以结合代码来理解一下
class ShouldUpdate extends Component {
shouldComponentUpdate (props, state) {
// isEqual 利用的是lodash工具库更新深拷贝的对比 也可以利用JOSN.stringify来转化成字符创比较 效果一样
if ( _.isEqual(props, this.props) && _.isEqual(state, this.state)) {
return false
}
return true
}
}复制代码
PureComponent
React.PureComponent
与 React.Component
几乎完全相同,但 React.PureComponent
通过prop和state的浅对比来实现 shouldComponentUpate()
。
React.PureComponent
的 shouldComponentUpdate()
只会对对象进行浅对比。如果对象包含复杂的数据结构,它可能会因深层的数据不一致而产生错误的否定判断(表现为对象深层的数据已改变视图却没有更新)。当你期望只拥有简单的props
和state
时,才去继承 PureComponent
,或者在你知道深层的数据结构已经发生改变时使用 forceUpate()
。或者,考虑使用 不可变对象 来促进嵌套数据的快速比较。
forceUpdate( ) :来使用 强制更新 在需要强制更新的组件内使用
component.forceUpdate(callback)
this.forceUpdate(callback) 来使用 强制更新 在需要强制更新的组件内使用 复制代码
默认情况,当你的组件或状态发生改变,你的组件将会重渲。若你的render()
方法依赖其他数据,你可以通过调用forceUpdate
()
来告诉React组件需要重渲。 调用forceUpdate()
将会导致组件的 render()
方法被调用,并忽略shouldComponentUpdate()
。这将会触发每一个子组件的生命周期方法,不覆盖子组件的shouldComponentUpdate()
方法。 若当标签改变,React
仅会更新DOM
。通常你应该尝试避免所有forceUpdate()
的用法并仅在render()函数里从this.props
和this.state
读取数据。
import React ,{Component,PureComponent} from 'react'
class Son extends PureComponent {
constructor(props){
super(props)
this.state = {
style:{ width:'100px',
height:'100px',
background: this.props.color // props改变 state不会更新
}}
}
render(){
return(
<div style = {this.state.style}>
{console.log('Son render()')}
</div>
)
}
componentWillReceiveProps(props,state){
this.forceUpdate() // 每次传递属性时 都会强制渲染 并忽略shouldComponentUpdate
if ( props.color === this.props.color ) return false;
this.setState((pre)=>{
let newStyle = {...pre.style}
newStyle.background = props.color
console.log(props.color)
return {style:newStyle}
})
}
}
class Father extends Component {
constructor(){
super()
this.state = {
color :'pink'
}
}
changeColor = (color)=>{
this.setState({
color:color
})
}
render(){
return(
<>
{console.log('Father render')}
<button onClick = {this.changeColor.bind(null,'black')}>blcak</button>
<button onClick = {this.changeColor.bind(null,'pink')}>pink</button>
<button onClick = {this.changeColor.bind(null,'yellow')}>yellow</button>
<Son color = {this.state.color}></Son>
</>
)
}
}
export default Father复制代码