1、说明
在生命周期中,子组件props或state更新都会触发shouldComponentUpdate生命钩子。该生命周期有两个参数nextProps,nextState 表示更新后的props和更新后的state, 该生命周期是整提高组件性能的一个重要函数,它通过判断当前状态与之前状态来返回一个布尔值并决定是否更新视图,如果返回false视图始终不会更新。返回true就会更新视图。
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate')
if(true) {
return true
} else {
return false
}
}
接下来我们来介绍一下props和state的使用。
2、state
前端框架从MVC过渡到MVVM。从DOM操作到数据驱动,一直在不断的进步着,提升着,angular中用的是watcher对象,vue是观察者模式,react就是state了,他们各有各的特点,没有好坏之分,只有需求不同而选择不同。
React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
constructor () {
// 必须在定义在内部state之前
// super指代父类实例,调用super继承父类的this对象
super();
this.state = { isLiked: false }
}
handleClickButton () {
// setState 方法由父类 Component 所提供。当我们调用这个函数的时候,React.js 会更新组件的状态 state ,
// 并且重新调用 render 方法,然后再把 render 方法所渲染的最新的内容显示到页面上。
// 注意,当我们要改变组件的状态的时候,不能直接用 this.state = xxx 这种方式来修改,
// 如果这样做 React.js 就没办法知道你修改了组件的状态,它也就没有办法更新页面。
// 所以,一定要使用 React.js 提供的 setState 方法,它接受一个对象或者函数作为参数。
this.setState({
isLiked: !this.state.isLiked
})
}
shouldComponentUpdate(nextProps,nextState) {
console.log("判断数据是否更新true,false来判断",nextProps,nextState)
return true
}
render() {
return (
<button onClick={this.handleClickButton.bind(this)}>
{this.state.isLiked ? '取消' : '点赞'}
</button>
)
}
}
export default App;
2.1 setState的使用
在使用state的时候, 如果我们企图直接修改state中的某一个值之后直接打印(使用)他,就会发现,他其实并没有改变。就像下面的例子,企图通过点击事件之后就使用修改之后的state的值,但是会发state中的并没有被立即修改,还是原先的值,我们都知道那是因为setState就相当于是一个异步操作,不能立即被修改
import React, {Component} from 'react';
import './App.css';
class App extends Component {
constructor () {
super();
this.state = { isLiked: false }
}
handleClickButton () {
console.log(this.state.isLiked,22)
this.setState({
isLiked: !this.state.isLiked
})
//和上面打印输出的结果一样。
console.log(this.state.isLiked,4444)
}
shouldComponentUpdate(nextProps,nextState) {
console.log("判断数据是否更新true,false来判断",nextProps,nextState)
return true
}
render() {
return (
<button onClick={this.handleClickButton.bind(this)}>
{this.state.isLiked ? '取消' : '点赞'}
</button>
)
}
}
export default App;
解决这种情况常见的有以下几种方式:
方法一:
class App extends Component {
constructor () {
super();
this.state = { isLiked: false }
}
handleClickButton () {
console.log(this.state.isLiked,223);
this.setState({
isLiked: !this.state.isLiked
},() => {
console.log(this.state.isLiked,333)
})
console.log(this.state.isLiked,4444)
//false 223
// false 4444
// true 333
}
render() {
return (
<button onClick={this.handleClickButton.bind(this)}>
{this.state.isLiked ? '取消' : '点赞'}
</button>
)
}
}
这个回调函数会在修改了state之后才会执行。
方法二:使用async / await
class App extends Component {
constructor () {
super();
this.state = { isLiked: false }
}
async handleClickButton () {
console.log(this.state.isLiked,223);
await this.setState({
isLiked: !this.state.isLiked
},() => {
console.log(this.state.isLiked,333)
})
console.log(this.state.isLiked,4444)
//false 223
//true 333
//true 4444
}
render() {
return (
<button onClick={this.handleClickButton.bind(this)}>
{this.state.isLiked ? '取消' : '点赞'}
</button>
)
}
}
2.3 总结
定义一个合适的State,是正确创建组件的第一步。因为有一些变量不需要响应式的使用,如果使用了state,就会给这个变量增加一些响应式挂载。
判断是否可以做为一个state的条件:
1、变量如果是通过props从父组件中获取,就不是一个状态
2、如果这个变量可以通过其他的状态state或者属性props 通过数据处理得到,就不是一个状态
3、如果变量在render中没有使用到,那就不是一个state
4、变量在整个生命周期中都保持不变时,也不是一个状态
4. props
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
import React, {Component} from 'react';
import './App.css';
class App extends Component {
render() {
return (
<div>
<Hello name='qishuixian' age="23" />
</div>
)
}
}
class Hello extends React.Component{
constructor(props){
super(props)
}
render(){
return <div>hello world + {this.props.name} + {this.props.age} + {this.props.year}</div>
}
}
Hello.defaultProps = {
year: '2018'
};
export default App;