react改變state的方法有:1、通過「this.setState({title:'React'});」方法修改state;2、通過「this.setState((preState, props)=>counter:preState.quantity+1)」方法修改state;3、通過「replaceState」方法改變元件的狀態。
本教學操作環境:Windows10系統、react18.0.0版、Dell G3電腦。
react有哪些方法改變state?
在react中正確修改state
不能直接修改state。
元件直接修改state,並不會重新觸發render。列如:
this.state.title='React';
登入後複製
正確修改方式是:
this.setState({title:'React'});
登入後複製
state的更新是非同步的
呼叫setState時,元件state並不會立即改變,而是把要修改的狀態放入事件佇列中,而react優化了真正的執行時機,並且出於本身效能原因,可能會將多次setState的狀態修改合併成一次狀態修改。因此不要依靠當前的state計算下一個state,因為當真正執行狀態修改時,有時候依賴的this.state並不能保證是最新的state,因為react本身會把多次state合併成一次,這時this.state還是舊state,因此也不能依賴當前的props計算下一個狀態,因為props的更新也是非同步。如:對於react常用的列子中有一個點選加號數值增加一的操作,點選一次+,數量會加1,如果連續點選兩次,還是會加1,這是在react合併修改為一次的情況下,相當與執行了如下程式碼:
Object.assign(
previousState,
{quantity:this.state.quantity+1},
{quantity:this.state.quantity+1},
)
登入後複製
於是後面覆蓋前面的操作,最終數值只加1,此時可以使用另一個函數作為引數的setState,這個函數有兩個引數,第一個引數是本次元件修改前的狀態,第二個引數是當前最新的props。
正確修改方式是:
this.setState((preState, props)=>counter:preState.quantity+1)
登入後複製
state的更新是一個合併的過程
當呼叫ssetState修改元件的狀態時,只需要傳入發生改變的state,而不是完整的state,因為元件state的更新時一個合併的過程,列如,一個元件的狀態為:
this.state={
title:'React',
content:'React is an wondeful JS library'
}
登入後複製
注:當只需要修改title時,將修改的title傳給setState即可:
this.setState({title:'ReactJs'});
登入後複製
react會合並最新的title到原來的狀態,同時保留原來狀態的content,最終合併state為:
this.state={
title:'ReactJs,
content:''React is an wondeful Js library
}
登入後複製
react官方把state當成不可變物件,一方面直接修改this.state,元件並不會重新render;另一方面,state中包含的所有狀態都應該是不可變的物件,當state當中的某一個狀態發生變化時,應該重新建立這個狀態物件,而不是直接修改原來的state狀態,那麼當狀態發生變化時,如何去建立新的狀態呢,我們根據狀態型別可以分為下面三種情況:
狀態型別為不可變型別(number,string,bool,bull,undefined)
這種情況最簡單,因為狀態是不可變型別,所以直接給要修改的狀態賦一個新值即可,列如下面我們要修改的count為number型,title(string),success(bool)三個狀態:
this.setState({
count:1,
title:'React',
success:true
})
登入後複製
狀態型別為陣列
假如有一個陣列型別的狀態books,當想books中增加一本書時,既可使用陣列的concat方法或者es6的擴充套件語法(apread syntax)
方法一:使用preState,concat建立新陣列
this.setState((preState)=>books:preState.books.concat(['React Guide']))
登入後複製
方法二:ES6 spread syntax
this.setState(preState=>books:[...preState,''React Guide])
登入後複製
當我們從books中擷取部分元素作為新狀態時,可以用陣列的slice方法:
this.setState(preState=>books:preState.books.slice(1,3))
登入後複製
當從books中過濾部分元素後,作為新狀態時,可以使用filter方法:
this.setState(preState => {
books: preState.books.filter(item => {
return item != 'React';
})
})
登入後複製
注意:不要使用push,pop,shift,unshift,splice登方法修改陣列型別的狀態,因為這些方法都是在原陣列的基礎上修改的,而concat,slice,filter會返回一個新的陣列。
方法三:狀態的型別是普通物件(不包含:string,array)
使用es6的Object.assgin()方法
this.setState({
onwer:Object.assgin({},preState.onwer,{name:'Jason'});
})
登入後複製
使用物件擴充套件語法(Object spread properties):
this.setState(preState=>{
owner:{...preState.owner,name:'Jason'}
})
登入後複製
總結:
建立新的狀態的關鍵是,避免使用會直接修改原物件的方法而是使用可以返回一個新物件的方法,當然可以使用Immutable的JS庫(Immutable.js)實現類似的效果。
思考:
為什麼React推薦元件狀態的修改時不可變物件呢?
replaceState()方法與setState()類似,但是方法只會保留nextState中狀態,原state不在nextState中的狀態都會被刪除。使用語法:
replaceState(object nextState,[, function callback])
登入後複製
nextState,將要設定的新狀態,該狀態會替換當前的state。
callback,可選引數,回撥函數。該函數會在replaceState設定成功,且元件重新渲染後呼叫。
如:
class App extends React.Component{
constructor(props);
this.state={
count:1
title:'數位計算'
}
}
handleClick=()=>{
this.replaceState({
count:this.state.count+1
})
}
render(){
return(
<button onClick={this.onClick}>點我</button>
)
}
}
登入後複製
結果為:
{
count:1
}
登入後複製
推薦學習:《》以上就是react有哪些方法改變state的詳細內容,更多請關注TW511.COM其它相關文章!