this.state = { count: 1 }
this.setState({
count: this.state.count + 1
})
console.log(this.state.count) // 1
this.setState((state, props) => {
return {
count: state.count + 1
}
})
console.log(this.state.count) // 1
this.setState(
(state, props) => {},
() => {console.log('这个回调函数会在状态更新后立即执行')}
)
this.setState(
(state, props) => {},
() => {
document.title = '更新state后的标题:' + this.state.count
}
)
class Hello extends Component {
componentDidMount() {
// timerId存储到this中,而不是state中
this.timerId = setInterval(() => {}, 2000)
}
componentWillUnmount() {
clearInterval(this.timerId)
}
render() { … }
}
class Hello extends Component {
shouldComponentUpdate() {
// 根据条件,决定是否重新渲染组件
return false
}
render() {…}
}
案例:随机数
class Hello extends Component {
shouldComponentUpdate(nextProps, nextState) {
return nextState.number !== this.state.number
}
render() {…}
}
class Hello extends Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.number !== this.props.number
}
render() {…}
}
class Hello extends React.PureComponent {
render() {
return (
<div>纯组件</div>
)
}
}
let number = 0
let newNumber = number
newNumber = 2
console.log(number === newNumber) // false
state = { number: 0 }
setState({
number: Math.floor(Math.random() * 3)
})
// PureComponent内部对比:
最新的state.number === 上一次的state.number // false,重新渲染组件
const obj = { number: 0 }
const newObj = obj
newObj.number = 2
console.log(newObj === obj) // true
state = { obj: { number: 0 } }
// 错误做法
state.obj.number = 2
setState({ obj: state.obj })
// PureComponent内部比较:
最新的state.obj === 上一次的state.obj // true,不重新渲染组件
// 正确!创建新数据
const newObj = {...state.obj, number: 2}
setState({ obj: newObj })
// 正确!创建新数据
// 不要用数组的push / unshift 等直接修改当前数组的的方法
// 而应该用 concat 或 slice 等这些返回新数组的方法
this.setState({
list: [...this.state.list, {新数据}]
})
不是
虚拟 DOM 配合 Diff 算法
虚拟 DOM:本质上就是一个 JS 对象,用来描述你希望在屏幕上看到的内容(UI)
{
type: 'div',
props: {
children: [
{ type: 'h1', props: {children: '随机数'} },
{ type: 'p', props: {children: 0} }
]
}
}
// ...省略其他结构
{ type: 'p', props: {children: 2} }
React 原理揭秘