2016-11-02 4 views
15

私はおそらく非常に明白な何かを見逃しているし、自分自身をクリアしたいと思います。リデュースする接続コンポーネントは、どのように再レンダリングするのかを知っていますか?

これは私の理解です。
ナイーブ反応成分において、我々はstates & propsを有する。 statesetStateに更新すると、コンポーネント全体が再描画されます。 propsはほとんどが読み取り専用であり、更新することは意味をなさない。

還元型ストアにサブスクライブする反応コンポーネントでは、store.subscribe(render)のようなものを介して、それは明らかにストアが更新されるたびに再描画されます。

react-redux

は通常

const TodoListComponent = connect(
    mapStateToProps, 
    mapDispatchToProps 
)(TodoList) 

のようなものを経由してでも理解した上で、コンポーネントにpropsような状態ツリーの一部(つまり、コンポーネントに関心がある)とactionCreatorsを注入ヘルパーconnect()を持っていますsetStateTodoListComponentが還元状態ツリーの変更(再レンダリング)に反応するために不可欠です。TodoListコンポーネントファイルにはstateまたはsetStateという関連コードが見つかりません。これは次のようなものです:

const TodoList = ({ todos, onTodoClick }) => (
    <ul> 
    {todos.map(todo => 
     <Todo 
     key={todo.id} 
     {...todo} 
     onClick={() => onTodoClick(todo.id)} 
     /> 
    )} 
    </ul> 
) 

私が紛失しているものについて正しい方向に指摘できますか?

P.S私はreduxパッケージ(https://github.com/reactjs/redux/tree/master/examples/todos/src/containers)にバンドルされているtodoリストの例に従っています。

答えて

25

connectファンクションは、ストアにサブスクライブするラッパーコンポーネントを生成します。アクションがディスパッチされると、ラッパーコンポーネントのコールバックが通知されます。次に、mapState関数を実行し、前回の結果オブジェクトと今回の結果オブジェクトを比較します。結果が異なる場合、それは小道具として、あなたの「本当の」部品」に結果を渡す。

それはのいずれかを示していないが、ダン・アブラモフ監督は、基本的な考え方を示して https://gist.github.com/gaearon/1d19088790e70ac32ea636c025ba424econnectの偉大な簡易版を書いた

また、私はRedux performanceのいくつかの関連するアイディアについての記事へのリンクを持っています。

+0

ありがとうございました!あなたは先日私を助けた同じ人ですか@ HN - https://news.ycombinator.com/item?id=12307621便利なリンクがありますか? お返事ありがとうございました:) –

+3

うわー、それは私です:Reddit、HN、SO、Medium、およびその他のさまざまな場所で、Reduxオンラインに関するディスカッションを過ごす時間が多すぎます。助けてうれしい! (ReasonifluxのチャットチャンネルをDiscordに置くことを強くお勧めします。たくさんの人が質問に答えてくれています。私は通常、夕方にオンラインにいます。EST。Invite linkはhttp://reactiflux.comです。) – markerikson

+0

質問に答えた、答えを受け入れる心? :) – markerikson

0

私の答えは、この投稿に私を導いた問題を明らかにしています。新しい小道具を受け取ったにもかかわらず、再現していないのです
React devsは、この(店舗)に突然変異があった場合、この99%の時間それは反応が再レンダリングされない理由です。 他の1%については何もありません。突然変異はここにはなかった。


TLDR;

componentWillReceivePropsstateが新しいpropsと同期に維持することができる方法です。

エッジケース:stateアップデートしたら、その後アプリ再レンダリングん!


それは、あなたのアプリがその要素を表示するためにstateを使用している場合、propsを更新することができますが、stateはないので、何も再レンダリングしていないことが判明します。

これは、storeから受け取ったpropsに依存するstateでした。私が必要とするデータは店舗にはないので、適切な通りcomponentDidMountに取り込んだ。私のコンポーネントはmapStateToProps経由で接続されているので、私のレデューサーがストアを更新すると、私は小道具を手に入れました。しかし、ページはレンダリングされず、状態は空の文字列でいっぱいでした。

たとえば、ユーザーが保存されたURLから「投稿の編集」ページを読み込んだとします。あなたはurlからpostIdにアクセスできますが、情報はまだstoreにはないので、それを取得します。あなたのページのアイテムは制御されたコンポーネントなので、表示しているすべてのデータはstateです。

reduxを使用すると、データが取得され、ストアが更新され、コンポーネントがconnectになりましたが、アプリケーションに変更が反映されません。近くを見ると、あなたは小道具を受け取ったが、アプリは更新されなかった。状態は更新されませんでした。

まあ、propsは更新されて伝播しますが、stateには反映されません。 stateに更新するように具体的に指示する必要があります。

render()でこれを行うことはできません。また、componentDidMountは既に完了しています。

componentWillReceivePropsは、変更されたprop値に依存するプロパティstateを更新する場所です。

使用例:

componentWillReceiveProps(nextProps){ 
    if (this.props.post.category !== nextProps.post.category){ 
    this.setState({ 
     title: nextProps.post.title, 
     body: nextProps.post.body, 
     category: nextProps.post.category, 
    }) 
    }  
} 

私は解決策で私を啓発し、この記事に叫び声を配る必要があります。その問題は、ここや数十の他の投稿、ブログ、レポにもたらされました!だから、この明らかにわかりにくい問題への答えを見つけるのが難しい他の誰かに、ここはそうです。

ReactJs component lifecycle methods — A deep dive

componentWillReceivePropsstateが新しいpropsと同期に維持することができる方法です。

state一度アップデート、その後再レンダリングしないアプリ!

関連する問題