2017-04-04 25 views
0

私はこの非常に単純なコンポーネントを持っています。これはredux状態に接続されており、{fruit, vegetables}を返します。すべてうまくいきますが、コンポーネント内にグラフがあり、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()の実装を支援するために、 shouldComponentUpdateフックが返すコンポーネントfalse。あなたの場合、Productsコンポーネントがレンダリングされると、Graphコンポーネントも同様です。

あなたはここに2つのオプションがあります。

  • あなたProductsコンポーネントがGraphコンポーネントの外fruit小道具を使用していない場合は、fruit状態に直接お使いのグラフコンポーネントを接続し、pureオプションを使用することができますfruitはあなたGraph共同でshouldComponentUpdateフックを定義することができ

  • を変更しないときに再描画しないようにするconnect機能の反応/ Reduxのアプリケーションを最適化する場所を手動でレンダリング不要のスキップ、またはあなたのためにそれを行うにはヘルパーライブラリを使用するmponent、例えばrecomposeライブラリのpureヘルパー

最初のオプションは、/不要避けることが始まり、一般的にレンダリングされます:コンポーネントを店舗に接続し、意味のある最低レベルに接続します。 2番目の選択肢は、より多くのエスケープハッチですが、それでもなお役に立つことがよくあります。

ステートレスコンポーネントを使用する場合は、高位コンポーネントを使用してshouldComponentUpdateフックの恩恵を受けることができます。それはあなたのステートレスをラップすることによって動作します。これは、あなたが不要避けるために、あなたのアプリケーション上で再利用することができpure HOCがレンダリングあなたを与えるだろう

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

を:これはどのように機能するかを理解するために、ここではどのようにそれを簡単に実装はこのようになりますコンポーネントを所望のフックで新しいコンポーネントに追加します。こののよりきめの細かい実装を持っている構図を見て、持つに

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

それでも、私は非常にあなたを奨励し、車輪の再発明をすることができないようになります。あなたは、たとえば、そのようにそれを使うだろう。

+0

問題を次のように同じように再レンダリングのためにそこにチェックを導入することができ、更新を取得したくない場合は、私が使用しているということですステートレスコンポーネント –

+0

を使用すると、この純粋なヘルパー(再構成)のような高次コンポーネントを使用できます。 'export default pure(MyStatelessComponent)'のようになります。 – VonD

+0

私は参照してください。私の上の問題を解決するために私が従うことができるどこかの例がありますか? –

2

新しい小道具を受け取ったときにコンポーネントが再レンダリングされないようにするには、shouldcomponentupdate()Graphに実装します。

コンポーネントの出力が状態または小道具の現在の変更の影響を受けていないかどうかをReactに知らせるには、shouldComponentUpdate()を使用します。デフォルトの動作は、すべての状態の変更に対して再レンダリングすることです。ほとんどの場合、デフォルトの動作に依存する必要があります。

shouldComponentUpdate()は、新しい小道具や状態を受け取ったときにレンダリングする前に呼び出されます。デフォルトはtrueです。このメソッドは、初期レンダリングまたはforceUpdate()が使用されているときは呼び出されません。

falseを返すと、子コンポーネントの状態が変わったときに子コンポーネントが再レンダリングされます。

現在、shouldComponentUpdate()がfalseを返した場合、componentWillUpdate()、render()、およびcomponentDidUpdate()は呼び出されません。将来、ReactはshouldComponentUpdate()をstrictディレクティブではなくヒントとして扱い、falseを返してもコンポーネントの再レンダリングが行われることに注意してください。

プロファイリング後に特定のコンポーネントが遅いと判断した場合は、shouldComponentUpdate()を実装するReact.PureComponentから継承するように変更することができます。手で書きたいと思っているなら、this.propsとnextPropsを比較し、this.stateをnextStateと比較し、falseを返して、Reactをスキップできるようにします。の例外で -

あなたはどちらか 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. 
    } 
関連する問題