react循环setstate_react -- 关于兄弟组件触发更新的问题
大家在用react的時候,應該都知道react的state更新會由父到子逐級更新的事情,那么就會有這樣一個問題,當要渲染的頁面元素較多,極端情況下,特別是大數據展示的時候,由頂層一點點逐級渲染,性能消耗太大。打個具體點的比方,有A,B,C三個組件,A是B,C的父組件,當應用場景是,B的某個動作需要C來相應的時候,傳統的做法如下。
class A extends React.Component {constructor(props) {super(props)this.state = {X: "",}}onChangeX=(v)=>{this.setState({X:v})}render() {return <div><B onChangeX={this.onChangeX}/><C X={this.state.X}/></div>} }class B extends React.Component {render() {return <div onClick={this.props.onChangeX}>{sample}</div>} } class C extends React.Component {render() {return <div>{this.props.X}</div>} }在這種代碼的實現下,由B觸發的事件必須經過父組件A所緩存的狀態才能更新到C,如果A本身Render的性能消耗大的話,比如A本身有很多的邏輯計算 或者A下面還有其它組件D,E,F,G,畫面渲染就非常耗時。那么有沒有什么辦法讓B觸發,繞過父組件A只更新目標C呢。
本人這里有兩個方案可供選擇。
第一,走redux
讓觸發點B不直接調用A的內部方法,而是發送redux更新用的Action。同時在被渲染的C組件外層包裹一個直接接收redux數據的container,數據由redux傳給C。關于redux和container就暫時不寫入代碼了(偷個懶)
class A extends React.Component {constructor(props) {super(props)this.state = {}}render() {return <div><B/><C/></div>} }class B extends React.Component {render() {return <div onClick={this.props.onChangeXAction}>{sample}</div>} } class C extends React.Component {render() {return <div>{this.props.X}</div>} }這個方法的好處是,條理清晰,代碼好讀。壞處是副作用太大,首先是當組件存在于一個比較大的應用的時候,redux的負擔過重,影響反應時間。其次是要想達到不觸發父組件A的目的,A本身就不能跟redux關聯,否則,redux的狀態動了,在沒有特殊控制的情況下,A也會被觸發更新。
第二個方法,把被渲染組件C的this傳給A,然后緩存下來。當被觸發的時候調用C自身的setState方法更新。代碼如下:
class A extends React.Component {constructor(props) {super(props)this.state = {// 組件C的對象緩存cInst: "",}}setCInst=(inst)=>{// 給緩存賦值this.setState({cInst:inst})}onChangeX=(v)=>{//由C自身對象的setState方法進行renderthis.cInst.setState({X:v})}render() {return <div><B onChangeX={this.onChangeX}/><C setCInst={this.setCInst}/></div>} }class B extends React.Component {render() {return <div onClick={this.props.onChangeX}>{sample}</div>} } class C extends React.Component {constructor(props) {super(props)this.state = {X: "",}}componentDidMount() {this.props.setCInst(this)}render() {return <div>{this.state.X}</div>} }這樣一來,當B開始觸發的時候,因為沒有調用A的setstate方法,A就不會重新渲染,從而達到提高性能的目的。當然,這種方法也有缺點,C組件的緩存是在componentDidMount生命周期上掛載的,那么在寫父組件的時候就要特別小心。比如本人在另一篇文章中【getDerivedStateFromProps 如何區分狀態更新來源】
閆松:react -- getDerivedStateFromProps 如何區分狀態更新來源?zhuanlan.zhihu.com之中寫到的方法,用隨機標志位來判斷區分跟新元,就不適用上面的代碼。原因是,當給子組件C加上key=隨機標志位 之后。每次A在渲染的時候,都會生成新的key。當新key生成的時候,react認為以前的子組件已經被拋棄了。會生成新的子組件,這時候新的子組件會重新執行componentDidMount生命周期,而建立緩存的時候,父組件又會重新render。這樣就會出現死循環。所以,當用以上方法時,切記不要加key或者加固定key,以免出現問題。
總結
以上是生活随笔為你收集整理的react循环setstate_react -- 关于兄弟组件触发更新的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis 启动_Redis介绍amp;
- 下一篇: cpu工作原理flash动画_cpu的基