setState
是React框架中,用于更新组件状态的方法。
setState
方法由React组件继承自 React.Component
类的一部分。通过调用 setState,可以告诉 React要更新组件的状态,并触发组件的重新渲染。
this.setState(newState, callback);
newState
是一个对象,它包含了需要更新的状态属性和值。它将合并到组件的当前状态中。
callback
是一个回调函数,它在 setState 更新状态完成之后被调用。
React框架中的“不可变值”的概念,通常指的是在编写React组件时,尽量避免直接修改数据,而是创建新的数据副本。
在React中,组件的状态(state)应该保持不变。通过使用 setState
方法更新状态时,React会合并现有状态和新状态,而不是直接修改状态。 这确保 React 可以正确地追踪状态的变化并进行必要的更新。
同时,直接修改数据可能会引发意外的副作用,尤其是在多个组件之间共享数据时。通过使用不可变值,可以减少出现这种问题的可能性。
常用的处理不可变值的工具包括 Object.assign
、数组的 concat
、slice
等方法。对数组或者对象使用slice()
方法,可以生成该数组或对象的副本,类似于深拷贝。
const list5Copy = this.state.list5.slice()
list5Copy.splice(2, 0, 'a') // 中间插入/删除
this.setState({
list1: this.state.list1.concat(100), // 追加
list2: [...this.state.list2, 100], // 追加
list3: this.state.list3.slice(0, 3), // 截取
list4: this.state.list4.filter(item => item > 100), // 筛选
list5: list5Copy // 其他操作
})
setState是一个异步方法。这意味着React可能会对多个 setState 调用进行批处理,然后一次性更新组件的状态,而不是每次调用都立即更新。
然而,setTimeout
函数中的 setState 是同步的。在自定义的DOM事件中,setState也是同步的。
state要在构造函数中定义
constructor(props){
this.state = {
count: 0
}
}
因为 setState 是异步的,因此在 setState 方法执行完后打印状态,是拿不到更新后的值,只能拿到当前状态的值。
this.setState({
count: this.state.count + 1;
})
console.log(this.state.count) //打印结果为 0
如果想要拿到最新的状态,需要在setState中,写一个回调函数。此时count的结果为1
this.setState(
{count: this.state.count + 1},() => {console.log(this.state.count)}
)
setTimeout
中的 setState
是同步的。此时打印出来的count结果就是1setTimeout(()=>{
this.setState({
count: this.state.count + 1
})
console.log(this.state.count) // 打印结果为1
}, 0)
bodyClickHandler = () => {
this.setState({
count: this.state.count + 1
})
console.log(this.state.count) // 打印结果为1
}
componentDidMount(){
document.body.addEventListener('click', this.bodyClickHandler)
}
constructor(props){
this.state = {
count: 0
}
}
this.setState({
count: this.state.count + 1
})
this.setState({
count: this.state.count + 1
})
this.setState({
count: this.state.count + 1
})
console.log(this.state.count) // 打印结果为 1
由于 setState 是异步的,React 会将这些更新一起批处理,然后应用它们。这意味着所有三个 setState 调用可能几乎同时执行,使用初始值 this.state.count,导致增加只有 1 而不是 3。
上述代码的思想类似于
Object.assign({count: 1}, {count: 1}, {count: 1}) // 执行结果为 {count: 1}
constructor(props){
this.state = {
count: 0
}
}
this.setState((prevState) => ({
count: prevState.count + 1
}));
this.setState((prevState) => ({
count: prevState.count + 1
}));
this.setState((prevState) => ({
count: prevState.count + 1
}));
console.log(this.state.count) // 打印结果为 3