react有哪些方法可以改變state

藏色散人
發布: 2023-01-06 09:18:14
原創
2416 人瀏覽過

react改變state的方法有:1、透過「this.setState({title:'React'});」方法修改state;2、透過「this.setState((preState, props)=> ;counter:preState.quantity 1)」方法修改state;3、透過「replaceState」方法改變元件的狀態。

react有哪些方法可以改變state

本教學操作環境:Windows10系統、react18.0.0版、Dell G3電腦。

react有哪些方法可以改變state?

在react中正確修改state

一,在react中可以透過this.state.{屬性}的方式直接取得state,但當我們想要修改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
}
登入後複製

 

二,state與不可變對象

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推荐组件状态的修改时不可变对象呢?

  1. 不可变对象的修改会返回一个新的对象,不用担心原对象在不小心的情况下修改导致的错误,方便程序的管理和调试
  2. 处于性能的考虑,对象组件的状态是不可变对象时,在组件的shouldComponentUpdate方法中仅需要比较前后两次状态对象的引用就可以判断状态是否真的改变,从而避免不必要的render调用

三:除了以上方法修改react组件的状态之外,我们还经常会用到replaceState改变组件的状态

 

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中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板