写篇文章攻克React——(6)讲解setState

556 阅读2分钟

setState是更新state刷新页面的接口,用于响应式,用于手动控制视图层刷新。

React 的核心思想是组件化的思想,应用由组件搭建而成,而组件中最重要的概念是State(状态),State是一个组件的UI数据模型,是组件渲染时的数据依据。比起vue将data中数据挂载到this上,react的状态仍然在state上。

setState

this.state通常只读,我们在react各种函数中使用setState完成this.state的更新并刷新UI视图,所以如果我们手动修改this.state就会被setState函数覆盖,无论是否修改不同属性。(这个props是类似的)

class App extends Component {
    constructor(el) {
        super(el)
        this.state = {
            clickCount: 0, 
            name: 'juejin',
            age: 18
        }
        this.change = this.change.bind(this);
    }
    change(){
        this.setState({clickCount: this.state.clickCount + 1})
    }
    render() {
        return (
            <div>
                <p>{this.state.clickCount}</p>
                <button onClick={this.change}>ok</button>
            </div>
        );
    }
}

使用

我们编写的事件函数或回调函数中使用setState完成视图层和UI渲染数据更新。所以函数本身在构造函数内,在原型上。

  • 参数一是需要更新的数据集合,参数二是回调函数:
this.setState({ clickCount: this.state.clickCount + 1 },()=>{
    console.log(this.state.clickCount);
})

我们在回调函数中this.state获取到的是更新后的状态。

this指向

如果我们没有在constructor中修改函数的this指向,就不能使用setState方法,使用就会报错:

image.png

  • 因为方法中的this已经不是组件里的this了,所以我们需要在constructor中修改函数的this指向
        this.change = this.change.bind(this);
  • 我们可以使用箭头函数来处理this问题:
    change=()=>{
        this.setState({clickCount: this.state.clickCount + 1})
    }

同步异步

setState本身是同步的,但是多种情况下,react项目会将setState推迟执行:

    change = () => {
        console.log(this.state.clickCount)
        this.setState({ clickCount: this.state.clickCount + 1 })
        console.log(this.state.clickCount)
    }
    componentWillUpdate()
    render()
    componentDidUpdate()

image.png

我通过执行生命周期函数打印发现,setState真正生效是componentWillUpdate生命周期函数后,在render之前。所以render会重新编译模板刷新视图层。

  • 所以我们不能在setState后立马使用this.state去获去状态,应该在componentDidUpdate和setState的回调函数中使用this.state

避免死循环

前面提到在事件函数或回调函数中调用setState进行状态更新,但是为了避免进入update的死循环中,我们应该避免在componentWillUpdate、render、componentDidUpdate去更新状态,因为一旦更新状态就会重新执行componentWillUpdate、render、componentDidUpdate生命周期函数。

通常循环50次react项目就会报错抛出bug。

image.png

除了使用setState修改state会引起当前组件刷新外,我们还可以修改props值来触发子组件刷新。