2017-04-04 46 views
0

我有這個非常簡單的組件,它連接到redux狀態並返回{fruit, vegetables}。一切工作正常,但假設我在Component和I中有一個圖表,如果從API每次只接收更新的vegetable,圖形將被重新創建。Redux mapStateToProps多次調用

這裏是我的組件:

const Products = ({ fruit, vegetable }) => 
    <div className='Products'> 
     <div>{vegetable.map(....logic here)}</div> 
     <div>{Math.random()}</div> // this is to illustrate the component is rendering every time 
     <Graph>Here will be a chart or a graph with fruit</Graph> //but it gets re-rendered even though there is no new fruit 
    </div> 

const mapStateToProps = (state) => { 
    return { 
    fruit: state.data.fruit, 
    vegetable: state.data.vegetable, 
    } 
} 

export default connect(mapStateToProps)(Products) 

在我看來,每一次,不管其中規定更新它重新呈現整個組件。

有沒有辦法阻止?

回答

1

當一個陣營組件被渲染,下面也被渲染組件的整個樹 - 在的異常其中shouldComponentUpdate掛鉤的組件返回false。所以在你的情況下,如果Products組件被渲染,Graph組件也是正常的。

你這裏有兩種選擇:

  • 如果您Products組件不使用Graph組件之外fruit道具,您可以將圖形組件直接連接到fruit狀態,並使用pure選項該connect功能,以避免重新呈現時fruit不會改變

  • 你可以在你Graph共同定義shouldComponentUpdate鉤mponent手動跳過不必要呈現,或使用一個輔助庫來爲你做,例如pure幫手recompose

的第一選項,其中優化反應/ Redux的應用/避免不必要的呈現通常始於:將您的組件連接到商店的最低級別,這是合理的。第二種選擇更多的是逃生艙口,但仍然很有用。

正如您所提到的,您使用無狀態組件,您可以使用更高階的組件從shouldComponentUpdate掛鉤中受益。要理解這是如何工作的,這裏有一個簡單的實現它怎麼會是這樣的:

function pure(BaseComponent, shouldUpdateFn) { 
    return class extends Component { 
     shouldComponentUpdate(nextProps) { 
      return shouldUpdateFn(this.props, nextProps); 
     } 
     render() { 
      return <BaseComponent { ...this.props } />; 
     } 
    } 
} 

這會給你一個pure HOC,你可以重複使用過您的應用程序,以避免不必要的渲染:它的工作原理是包裝無狀態組件到具有所需鉤子的新組件中。你會使用它像這樣,例如:

export default pure(Graph, (props, nextProps) => props.fruit !== nextProps.fruit) 

不過,我強烈建議你在看看重新合成,它具有的這種更細粒度的實現,並會避免你推倒重來。

+0

問題不在於我使用一個無狀態組件 –

+0

然後你可以使用一些更高階的組件來做這件事,就像這個純粹的幫助器重新構造一樣。它看起來像:'export default pure(MyStatelessComponent)'。 – VonD

+0

我明白了。有沒有一個例子可以解決我的上述問題? –

2

要防止組件在接收新道具時重新渲染,您可以在Graph中實現shouldcomponentupdate()

使用shouldComponentUpdate()讓React知道組件的輸出是否不受當前狀態或道具變化的影響。默認行爲是在每次狀態更改時重新呈現,在絕大多數情況下,您應該依賴默認行爲。

當接收到新的道具或狀態時,會在渲染前調用shouldComponentUpdate()。默認爲true。此方法不用於初始渲染或使用forceUpdate()時。

返回false不會阻止子組件在其狀態更改時重新呈現。

當前,如果shouldComponentUpdate()返回false,則不會調用componentWillUpdate(),render()和componentDidUpdate()。請注意,將來React可能會將shouldComponentUpdate()作爲提示而不是嚴格指令,並且返回false仍可能導致組件的重新呈現。

如果您確定某個特定組件在分析後速度較慢,則可以將其更改爲從React.PureComponent繼承,React.PureComponent實現了shouldComponentUpdate()以及較淺的prop和state比較。如果你確信你想用手寫它,你可以將this.props與nextProps和this.state與nextState進行比較,並返回false以告訴React更新可以被跳過。

爲了幫助您實現shouldComponentUpdate(),您可以使用React shallow-compare()或自定義的淺比較功能

2

鑑於您當前的代碼。 當狀態改變時,React將更新整個組件。 因此圖形組件將被更新。

如果你不想圖表組件來獲得更新,你可以在你的圖形組件添加shouldComponentUpdate並引入檢查有沒有重新呈現類似如下

shouldComponentUpdate: function(nextProps, nextState) { 
    // You can access `this.props` and `this.state` here 
    // and check them against nextProps and nextState respectively. 
    // return boolean(false) if you don't want the component to re-render. 
    } 
相關問題