react中的setState特點:
- 是異步操作函數;
- 組件在還沒有渲染之前, this.setState 還沒有被調用;
- 批量執行 State 轉變時讓 DOM 渲染更快(相對比一個一個的setState的來的快)。
例如:{count:0}//初始化count
this.setState({count:1});
console.log(this.state.count);
setState函數並不會阻塞等待狀態更新完畢。所以,打印出來的並不是count=1,而還是count=0。
很多時候,我們需要想要的state狀態更新完成后再進行某些操作。此時,我們可以選擇在componentWillUpdate生命周期或者componentDidUpdate生命周期的回調函數去執行我們的操作。雖然也可以達到預期效果,但是這樣做不是最佳方法,代碼變得破碎,可讀性也不好。
因此,此時我們就需要保證setState的同步更新。
- setState支持回調函數
第一個參數是我們要設置的state,第二個參數是在狀態更新完畢后的回調操作
this.setState({count:1},()=>{ console.log(this.state.count)//輸出count=1 });
- ES7的Async/Await實現異步轉同步
var delay = function (time) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, time); }) }; var start = async function () { console.log('a'); await delay(2000); console.log('b'); }; start();//先輸出a,稍等2秒后,輸出了b
同樣在react中的應用:
Promise來封裝setState: setStateAsync(state) { return new Promise((resolve) => { this.setState(state, resolve) }); } async componentDidMount() { await this.setStateAsync({count: 1}); console.log(this.state.count);//輸出count=1 }
- async 表示這是一個async函數,await只能用在這個函數里面。
- await 表示在這里等待promise返回結果了,再繼續執行。
- await 后面跟着的應該是一個promise對象
附錄:
class Example extends React.Component { constructor() { super(); this.state = { val: 0 }; } componentDidMount() { this.setState({val: this.state.val + 1}); console.log(this.state.val); // 第 1 次 log->0 this.setState({val: this.state.val + 1}); console.log(this.state.val); // 第 2 次 log->0 setTimeout(() => { this.setState({val: this.state.val + 1}); console.log(this.state.val); // 第 3 次 log->2 this.setState({val: this.state.val + 1}); console.log(this.state.val); // 第 4 次 log->3 }, 0); } render() { return null; } };
