2016-08-21 7 views
0

私は単一のストアの現在の状態に基づいてルーティングする単純なルータを作成しました。ルータはそれぞれの子を調べ、その状態を抽出してselect edとし、ルートがそのwhenプロパティに従って表示されるべきかどうかをテストします。シンプルストアベースのルータで不要な再レンダリング

var Router = React.createClass({ 
    render: function() { 
    const {children, state} = this.props; 
    const activeRoute = React.Children.toArray(children).find(when); 

    return React.createElement(
     activeRoute.props.component, 
     Object.assign(
     {}, 
     activeRoute.props.select(state), 
     { 
      setState: this.props.setState, 
     } 
    ) 
    ); 

    function when(child) { 
     return child.props.when(child.props.select(state)); 
    } 
    } 
}); 

var Route = React.createClass({ 
    getDefaultProps: function() { 
    return { 
     select: identity, 
     when: alwaysTrue, 
    } 
    }, 

    render: function() { 
    throw new Error('Route should never render'); 
    }, 
}); 

これらのコンポーネントは、このように使用できます。

<Router state={this.state} setState={this.sState}> 
    <Route component={Pets} when={this.onPets} select={this.selectPets} /> 
    <Route component={Home} /> 
</Router> 

why-did-you-updateを使用して、私はそれが不必要に再描画していることがわかりました。私はこれらの不要な再レンダリングを排除したいと思いますが、そうすることはできません。再レンダリングの原因は何ですか?どうすればそれらを避けることができますか?

実用デモhereがあります。 「ペットを見る(ここをクリックしてください)」をクリックすると、一連の回避可能な再レンダリングの警告が表示されます。

答えて

0

why-did-you-updateは、2つのレンダリング間のchildrenプロパティは同じですが、同じ参照ではないため、私たちに警告しています。これは、各レンダリングで新しいReact.createElementを返すために発生します。

これを修正するには、childrenthis.propsthis.state、プロパティをapp、またはグローバルに移動することができます。 createClassの代わりにes6クラスを使用していた場合、インスタンス変数を作成できました。これらのメソッドの1つを使用して、childrenをレンダリングメソッドに渡すことができます。

<Router state={this.state} setState={this.sState} children={routes} /> 

実例はhereです。

関連する問題