this.setState的详细用法

1.为什么不要直接对state进行赋值?

如果直接对this.state复制是不会去更新视图的,this.setState的原理是同一个队列来实现state的更新的,将需要更新的state放入到状态队列中,在一定时间段之后,合并并更新state,然后进行渲染.而直接对this.state赋值是不会有这些操作的,因此不要对state进行直接赋值.

2.this.setState为什么是异步的?

this.setState的操作是异步的,是为了提升性能对state的更新进行批量操作,官方文档中的原话:

将 setState() 视为请求而不是立即更新组件的命令。为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。

如果每一次的调用this.setState都去更新state和渲染组件,这对浏览器来说是一个很大开销。因此就需要这种批量操作以达到性能的提升。

3.如果this.setState是异步的,那么在使用当前状态去更新下个状态的时候,由于当前的state可能不是最新的,就会出现问题;那怎么解决?

class Welcome2 extends React.Component{
    constructor(props) {
        super(props);
        this.state={a:1};
    }
    componentDidMount() {
        console.log(this.state);//a:1
        this.setState({a:this.state.a+1});
        console.log(this.state);//a:1
        this.setState({b:this.state.a});
        console.log(this.state);//a:1
    }

    render() {
        return <h1>{this.state.a}</h1>
    }
}

this.setState的第一个参数是可以接受一个函数的,在这个函数中第一个参数是state,第二个参数是props,其中state一定是最新的。

class Welcome2 extends React.Component{
    constructor(props) {
        super(props);
        this.state={a:1};
    }
    componentDidMount() {
        console.log(this.state,"a");//a:1  a
        this.setState((state)=>({
            a:state.a+1
        }));
        console.log(this.state,"b");//a:1  b
        this.setState((state)=>{
            console.log(this.state,state);//a:1  a:2 
            return {b:state.a}
        });
        console.log(this.state,"c");//a:1  c
    }

    render() {
        return <h1>{this.state.a} and {this.state.b}</h1>;//最终b也会被渲染到页面上
    }
}

4.在批量更新时,React 总会按照定义顺序进行浅合并。

this.setState({ a: 1 });
this.setState({ b: 2 });
this.setState({ c: 3, a: 'a' });

//最终结果:  a:a  b:2  c:3 

 看一下的代码最终输入多少?

class Welcome3 extends React.Component{
    constructor(props) {
        super(props);
        this.state={
            a:1,
            count:0
        };
    }
    componentDidMount() {
        const incrementChange = state => ({ count: state.count + 1 })
        this.setState(incrementChange)   //1
        this.setState(incrementChange)   //2
        this.setState({ count: this.state.count + 1 })   //3
        this.setState(incrementChange)   //4
    }

    render() {
        return <h1>{this.state.count}</h1>
    }
}

最终在页面渲染的是2。由于第一步和第二部采用传入的函数的方式进行更新状态,所以在第二步之后count 的值就是2,在第三步中,由于并没有渲染,因此当前this.state.count是0,在进行浅合并之后,第三步执行完之后,count的值为1,第四步中就是将count赋值成1+1为2,因此输出是2。由此我们可以知道,无论第三步前执行了多少次setState,在第三步赋值的时候this.state.count都是0,浅合并之后count的值都会是1,输出的结果也都是2。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值