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视频教程》
以上是react有哪些方法可以改變state的詳細內容。更多資訊請關注PHP中文網其他相關文章!