setState(updater,[callback])react
updater 爲返回stateChange的函數的對象,(state,props) => stateChange面試
接收的state和props被保證爲最新的promise
函數方式:babel
1、若是新狀態依賴於原狀態
this.setState((state,props) => ({
count: state.count+1
}),()=>{
// callback
})
複製代碼
setState(stateChange,[callback])dom
stateChange爲對象異步
callback是可選的回調函數,在狀態更新且界面更新後才執行函數
對象方式:測試
1、新狀態不依賴於原狀態 ==>使用對象方式
this.setState({count:this.state.count+1},()=>{
// callback
})
複製代碼
<body>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count:0
}
}
test1 = ()=> {
// 若是新狀態依賴於原狀態,使用函數方式
this.setState((state,props)=> ({
count: state.count+1
}))
console.log('test1以後獲取count的值:',this.state.count); // 0
}
test2 = ()=> {
// 新狀態不依賴於原狀態 ==>使用對象方式
const count = this.state.count + 1;
this.setState({count});
console.log('test2以後獲取count的值:',this.state.count);
}
test3 = ()=> {
this.setState(state =>({
count: state.count + 1
}),()=>{
console.log('test3-----setState回調函數中count的值:',this.state.count);
})
}
render() {
return (
<div>
<h1>A組件:{this.state.count}</h1>
<button onClick={this.test1}>測試1</button><br />
<button onClick={this.test2}>測試2</button><br />
<button onClick={this.test3}>測試3</button><br />
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'));
</script>
</body>
複製代碼
setState()內部是利用的 「事務」 實現異步更新狀態ui
定時器,DOM事件監聽回調,Promisethis
在react控制的回調函數中:生命週期鉤子 、 react事件監聽的回調
注意:異步狀況
在setState()的callback回調函數中
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count:0
}
}
/** * react事件監聽相關的回調中:- setState()是異步更新狀態的 */
test1 = ()=> {
console.log('setSate回調函數以前---react事件監聽回調',this.state.count);
this.setState(state=>({
count:state.count+1
}))
console.log('setSate回調函數以後---react事件監聽回調',this.state.count);
}
/** * react生命週期鉤子中:- setState()是異步更新狀態的 */
componentDidMount() {
console.log('setSate回調函數以前---生命週期鉤子',this.state.count);
this.setState(state=>({
count:state.count+1
}))
console.log('setSate回調函數以後--生命週期鉤子',this.state.count);
}
// 同步 (定時器,DOM事件監聽回調,Promise)
test2 = ()=> {
setTimeout(() => {
console.log('setSate回調函數以前---定時器',this.state.count);
this.setState(state=>({
count:state.count+1
}))
console.log('setSate回調函數以後---定時器',this.state.count);
}, 0);
}
test4 = () => {
const btn4 = this.refs.btn4;
btn4.onclick = ()=> {
console.log('setSate回調函數以前---原生DOM',this.state.count);
this.setState(state=>({
count:state.count+1
}))
console.log('setSate回調函數以後---原生DOM',this.state.count);
}
}
test3 = ()=> {
Promise.resolve().then(res => {
console.log('setSate回調函數以前---Promise',this.state.count);
this.setState(state=>({
count:state.count+1
}))
console.log('setSate回調函數以後---Promise',this.state.count);
})
}
test5 = ()=> {
console.log('setState 函數方式 - 1 --調用前',this.state.count);
this.setState(state => ({
count: state.count+1
}))
console.log('setState 函數方式 - 1 --調用後',this.state.count);
this.setState(state => ({
count: state.count+1
}))
console.log('setState 函數方式 - 2 --調用後',this.state.count);
}
test6 = ()=> {
console.log('setState 對象方式 - 1 --調用前',this.state.count);
this.setState({count:this.state.count+1});
console.log('setState 對象方式 - 1 --調用後',this.state.count);
this.setState({count:this.state.count+1});
console.log('setState 對象方式 - 2 --調用後',this.state.count);
}
test7 = () => {
console.log('setState 對象方式 - 1 --調用前',this.state.count);
this.setState({count:this.state.count+1});
console.log('setState 對象方式 - 1 --調用後',this.state.count);
this.setState(state => ({
count: state+1
}));
console.log('setState 函數方式 - 1 --調用後',this.state.count);
}
render() {
return (
<div> <h1>A組件:{this.state.count}</h1> <button onClick={this.test1}>測試1</button><br /> <button onClick={this.test2}>測試2</button><br /> <button onClick={this.test3}>Promise</button><br /> <button ref="btn4" onClick={this.test4}>原生DOM</button><br /> <button onClick={this.test5}>setState屢次調用---函數方式</button><br /> <button onClick={this.test6}>setState屢次調用---對象方式</button><br /> <button onClick={this.test7}>setState屢次調用---對象方式和函數方式</button><br /> </div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root')); </script>
複製代碼
若是上面講解的內容都能理解的,下面的內容很容易的。🙂
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<div id="root"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
count:0
}
}
/** * Promise和定時器相比,promise會先執行 * setState()執行一次,致使數據發生變化,就會觸發render的更新 */
componentDidMount() {
this.setState({count:this.state.count+1});
this.setState({count:this.state.count+1});
console.log('1----',this.state.count); // 2 --> 0(上面兩個會被合併成一個)
this.setState(state => ({
count: state.count+1
}))
this.setState(state => ({
count: state.count+1
}))
console.log('2-----',this.state.count); // 3 --> 0 (第四次執行,輸出結果爲3)
setTimeout(() => {
this.setState({count:this.state.count+1});
console.log('timeout-1',this.state.count); // 8 ---> 6
this.setState({count:this.state.count+1});
console.log('timeout-2',this.state.count); // 10 ---> 7
}, 0);
Promise.resolve().then(value=>{
this.setState({count:this.state.count+1});
console.log('promise-1',this.state.count); // 5 --> 4
this.setState({count:this.state.count+1});
console.log('promise-2',this.state.count); // 7 --> 5
})
}
render() {
const count = this.state.count;
console.log('render',count); // 1 --- 0 , 4 ---> 3, 6 ---> 4 , 9 ---> 6,11 --> 7
return (
<div> <h1>A組件:{this.state.count}</h1> </div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root')); </script>
複製代碼