通例狀況
在同一個要領中屢次setState是會被兼并的,而且對雷同屬性的設置只保存末了一次的設置;
import React from 'react';
export class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentWillMount() {
let me = this;
me.setState({
count: me.state.count + 2
});
me.setState({
count: me.state.count + 1
});
}
componentDidMount() {
let me = this;
me.setState({
count: me.state.count + 2
});
me.setState({
count: me.state.count + 1
});
}
onClick() {
let me = this;
me.setState({
count: me.state.count + 1
});
me.setState({
count: me.state.count + 1
});
}
render() {
console.log(this.state.count);
console.log('1111111111111111111111111111111111111111111');
return (
<div>
<h1>{this.state.count}</h1>
<input type="button" value="點擊我" onClick={this.onClick.bind(this)} /><br />
<br />
</div>
)
}
}
上述實行歷程以下:
willmount
中的setState
會兼并成一次實行,count
只會保存末了一次的設置,前面的摒棄,所以willmount
以後是1
,並非3
;而且在render
之前實行,不會激發新的render
- render以後實行didMount,setState做一樣的處置懲罰,這是
count
是2
,而且激發新的render- 點擊按鈕,
setState
做一樣處置懲罰,count
是3
,激發新的render
定時器中的setState
定時器中的setState,每次都邑激發新的render,即使是同一個定時器中的屢次setState
代碼更改成以下:
componentWillMount() {
let me = this;
setTimeout(() => {
me.setState({
count: me.state.count + 1
});
me.setState({
count: me.state.count + 1
});
}, 0);
}
componentDidMount() {
let me = this;
setTimeout(() => {
me.setState({
count: me.state.count + 1
});
me.setState({
count: me.state.count + 1
});
}, 0);
}
onClickTime() {
let me = this;
setTimeout(() => {
me.setState({
count: me.state.count + 1
});
me.setState({
count: me.state.count + 1
});
}, 0);
}
上述代碼,每次
setState
都邑激發新的render,須要深切相識的能夠查查
setState
的道理,簡樸明白是定時器中的
setState
沒走
react
的事物機制,實行時批量更新沒被設置
true
,所以每次都直接render了。
原生事宜中的setState
在按鈕原生事宜中定義的
setState
,和定時器結果一樣,
每次setState
都邑激發新的render
react事宜是兼并的成一次render的。
componentDidMount() {
this.button.addEventListener('click', this.onClick.bind(this, '原生事宜'), false);
}
onClick(info) {
console.log(info);
this.setState({
count: ++count
});
this.setState({
count: ++count
});
}
render() {
console.log(this.state.count);
return <div>
<input type="button" ref={input => this.button = input} onClick={this.onClick.bind(this, 'React事宜')} value="天生計時器" />
<div>Count:{this.state.count}</div>
</div>
}
點擊按鈕,先實行原生事宜,再實行react事宜,然則原生事宜會觸發兩次render,react事宜觸發一次。
總結
上述是我對setState的明白,舉一反三,願望協助人人有方向的去相識react道理機制。剛開始打仗,許多同硯想深切相識,但可能不曉得從何入手,這也是我遇到過的攪擾,所以如今分享出來,願望能協助人人少走彎路,更快的、更有準針對性的去研究學習React。
以下為補充內容
回調不會觸發react的批量更新機制
其實在回調函數中,setState是不會觸發批量更新機制的,無論是promise,ajax,setTimeout回調等等,同時設置屢次setState,每一個setState都邑零丁實行並render,由於上下文發生了變化。
下面是考證code
onClickBtn = () => {
// const promise = new Promise((resolve, reject) => {
// this.setState({ count: this.state.count + 1 });
// console.log(this.state.count);
// this.setState({ count: this.state.count + 1 });
// console.log(this.state.count);
// resolve();
// });
// promise.then(() => {
// this.setState({ count: this.state.count + 1 });
// console.log(this.state.count);
// this.setState({ count: this.state.count + 1 });
// console.log(this.state.count);
// });
fetch("/api/getlist")
.then(response => {
return response.json();
})
.then(data => {
console.log(JSON.stringify(data));
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
this.setState({ count: this.state.count + 1 });
console.log(this.state.count);
});
};
生命周期和事宜中屢次setState的區分
在寫demo時發明,雖然didMount
中的屢次setState
會被兼并,相符一般的規律,然則經由過程調試發明,在didMount
中isBatchingUpdates
始終是false
,而事宜挪用觸發的setState
,isBatchingUpdates
則是true
。