2016-08-09 7 views
4

React-Reduxを理解しようとすると、状態のスライスが変更されたときに、すべてのコンポーネントが新しい小道具を得るのは珍しいことです。これは設計によるものなのですか、何か間違ったことをしていますか?このアプリでは大丈夫変更の影響を受けたコンポーネントのみを更新するReduxを制限する

例のApp

class App extends React.Component { 

    render(){return (
      <div> 
      <Navbar data={this.props.navbar} /> 
      <Content data={this.props.content} /> 
      </div>); 
    } 

} 
select (state) => ({ navbar:state.navbar, content:state.content}); 
export default connect(select)(App); 

コンポーネント

export const NavbarForm = props => { 
    console.log('RENDERING with props--->',props); 
    return (<h1>NAV {props.data.val}</h1>); 
}; 
export const ContentForm = props => { 
    console.log('RENDERING CONTENT with props--->',props); 
    return (<h1>CONTENT {props.data.val}</h1>); 
}; 

////////INDEX.js////// 

const placeholderReducer = (state={val:0},action)=>{ 
//will update val to current time if action start with test/; 
if(action.type.indexOf('TEST/') === 0)return {val:Date.now();} 

return state; 
} 

export const rootReducer = combineReducers({ 
    navbar:placeholderReducer, 
    content: (state,action)=>(state || {}), //**this will never do a thing.. so content should never updates right !!** 
}); 

const store = createStore(rootReducer, {}, applyMiddleware(thunk)); 

render(<Provider store={store}> <App /></Provider>, document.getElementById('app') 
); 
setInterval(()=>{ store.dispatch(()=>{type:'TEST/BOOM'}) },3000); 

、私は何を期待することは、コンテンツのコンポーネントが更新されることはありませんしながら、ナビゲーションバーのコンポーネントがすべての3000msに更新されますということですその減速はするので、常に同じ状態を返します。

まだ私は、アクションが実行されるたびに両方のコンポーネントが再レンダリングを行うのは本当に奇妙なことがわかります。

これは仕様です。私のアプリが100以上のコンポーネントを持っている場合、私はパフォーマンスについて心配すべきですか?

+0

あなたのアプリは、パフォーマンスの面で十分に拡張しませんが、私はあなたの主な質問にお答えします。 Navbarの機能コンポーネントをクラスベースのコンポーネントに変換し、ライフサイクルメソッド 'componentWillReceiveProps(nextProps) 'を追加して状態を設定します。詳細については、[here](https://facebook.github.io/react)を参照してください。 /docs/component-specs.html#updating-componentwillreceiveprops) –

+0

@AdegbuyiAdemolaなぜそれが規模にならないのですか?これはreduxのdocsからのpropsed構造ではありませんか?あなたは精緻化できますか?ライフサイクルの追加はどのように反作用による小道具の更新を防ぎますか? – Zalaboza

+0

ストアに問題が発生した場合は、最大スタックを超過した可能性があります。私は、ライフサイクルを追加することで反応を減らすことはできないと言っていませんでした....つまり、NavbarでもNavbarをクラスベースのコンポーネントにする必要があります。 –

答えて

8

これは完全に設計によるものです。 Reactは、あなたのアプリケーション全体がデフォルトで再描画されることを前提としています。あるいは、特定のコンポーネントがsetStateかそれに類似している場合、少なくとも与えられたサブツリーはレンダリングされません。

あなたのアプリには一番上のコンポーネントが接続されているだけなので、その上からすべてがReactの標準的な動作です。親コンポーネントが再レンダリングされ、すべての子が再レンダリングされ、のすべての子がの子を再レンダリングします。

ReactのUIパフォーマンスを向上させるためのコアアプローチは、shouldComponentUpdateライフサイクルメソッドを使用して着信小道具をチェックし、コンポーネントを再レンダリングする必要がない場合はfalseを返します。これにより、Reactはそのコンポーネントの再レンダリングをスキップします。およびすべての子孫を再レンダリングしません。 shouldComponentUpdateの比較は、一般的に浅い参照平等を使用して行われます。これは、「同じオブジェクト参照が更新しない」ということが有用になる場所です。

Reduxとconnectを使用している場合、UIの多くのコンポーネントでconnectを使用していることがほとんどです。これには多くのメリットがあります。コンポーネントは、ルートコンポーネントからすべてを取り出す必要はなく、必要なストアステートを個別に抽出できます。さらに、connectshouldComponentUpdateのデフォルト値を実装しています。は、mapStateToProps関数から返された値について同様のチェックを行います。だから、ある意味では、複数のコンポーネントにconnectを使用すると、パフォーマンスに関して「自由な勝利」を得る傾向があります。トピックの

さらに読書:

5

はいこれは仕様です。アクションがディスパッチされます。リデューサーが走ります。店の購読者は「店舗が変更されました」という通知を受け取ります。接続されたコンポーネントはストア加入者です。

通常、パフォーマンスの問題を実際に測定するまでは心配する必要はありません。これは、早すぎて最適化しないでください。

あなたはそれが問題であることが判明した場合、その後、あなたは、次のいずれかを行うことができます

  • 彼らは、彼らが受け取った小道具がないことを確認できるように、あなたのコンポーネントにshouldComponentUpdateメソッドを追加します。 (レンダリングする必要はありません。)
  • トップレベルのアプリケーションを接続する代わりに、NavbarコンポーネントとContentコンポーネントを直接接続します。アプリは決して元に戻すことはありませんが、ストアが変更された場合、子供たちはそれを行います。また、react-reduxは自動的にshouldComponentUpdateを使用して、実際に新しい小道具を持つ接続されたコンポーネントのみを再レンダリングします。
+0

もう2つのことをお勧めします.Perfツールを使ってReact 15.3以降の[React.PureComponent](https://github.com/facebook/react/blob/master/CHANGELOG.md)を最適化して使用する必要がある(該当する場合) –

関連する問題