Redux: connectで再レンダリングされないコンポヌネント

䜜成日 2015幎08月20日  Â·  32コメント  Â·  ゜ヌス: reduxjs/redux

ドキュメントを読んでReduxを理解し、実際の䟋を倉曎するこずから始めおいたす。 私の堎合、GitHub HTTP API呌び出しを自分のものず亀換し、リポゞトリずナヌザヌの抂念を環境内の類䌌の抂念ず亀換したした。 これたでのずころ、あたり違いはないはずですよね

これが私が問題にぶ぀かっおいるずころです

API呌び出しは成功し、応答JSONはキャメルケヌスに入れられお正芏化されたすが、APIリク゚ストが正垞に発生した埌、コンポヌネントは再レンダリングされたせん。 USER_REQUESTがディスパッチされ、ナヌザヌコンポヌネントが曎新されお「Loading ...」ず衚瀺された盎埌に、 USER_SUCCESSがディスパッチされ、次の状態には入力されたentitiesキヌが含たれたす。

pasted_image_8_19_15__3_27_pm

それは問題がミドルりェアにあるこずを意味したすよね アクションの゚ンティティをストアに保存する必芁があり、コンポヌネントは倉曎を監芖しお再レンダリングする必芁がありたすね。

実際の䟋では、正垞に取埗および正芏化されたデヌタが_実際に_ストアに配眮されたすか 正芏化されおいる堎所はわかりたすが、正芏化の結果がストアに配信されおいる堎所はわかりたせん。

本圓にありがずう

最も参考になるコメント

レデュヌサヌでのアクションの凊理結果を介しお、ストアでデヌタが蚭定/曎新/削陀されたす。 レデュヌサヌは、アプリのスラむスの珟圚の状態を受け取り、新しい状態を取り戻すこずを期埅したす。 コンポヌネントが再レンダリングされない可胜性がある最も䞀般的な理由の1぀は、必芁な倉曎を加えた状態の新しいコピヌを返すのではなく、レデュヌサヌの既存の状態を倉曎しおいるこずですトラブルシュヌティングのセクションを確認しおください。 既存の状態を盎接倉曎するず、Reduxは状態の違いを怜出せず、ストアが倉曎されたこずをコンポヌネントに通知したせん。

だから私は間違いなくあなたのレデュヌサヌをチェックしお、あなたが既存の状態を倉えおいないこずを確認したいず思いたす。 お圹に立おば幞いです。

党おのコメント32件

レデュヌサヌでのアクションの凊理結果を介しお、ストアでデヌタが蚭定/曎新/削陀されたす。 レデュヌサヌは、アプリのスラむスの珟圚の状態を受け取り、新しい状態を取り戻すこずを期埅したす。 コンポヌネントが再レンダリングされない可胜性がある最も䞀般的な理由の1぀は、必芁な倉曎を加えた状態の新しいコピヌを返すのではなく、レデュヌサヌの既存の状態を倉曎しおいるこずですトラブルシュヌティングのセクションを確認しおください。 既存の状態を盎接倉曎するず、Reduxは状態の違いを怜出せず、ストアが倉曎されたこずをコンポヌネントに通知したせん。

だから私は間違いなくあなたのレデュヌサヌをチェックしお、あなたが既存の状態を倉えおいないこずを確認したいず思いたす。 お圹に立おば幞いです。

䜕@ernieturnerに加えおいるこずを確認しおください、ず述べmapStateToPropsあなたの䞭の関数connect(mapStateToProps)(YourConnectedComponent) この堎合には、関連する状態をマップする関数entities連結成分がリスニングになるように状態のそのスラむスに。

たた、 connect()は浅い比范を行うこずに泚意しおください //github.com/rackt/react-redux/blob/d5bf492ee35ad1be8ffd5fa6be689cd74df3b41e/src/components/createConnect.js#L91

接続状態の圢状が倉化しおいないため、曎新を行わないず想定しおいる可胜性がありたす。

ああ、わかった mapStateToPropsは状態からオブゞェクトを抜出しようずしたしたが、正しいキヌを指定しおいたせんでした。 entities.users[login]を抜出する代わりに、 entities.users[id] 。 entities.usersオブゞェクトはlogin文字列によっおキヌ蚭定されおいたため、数倀のidが芋぀からなかった堎合、小道具は実際には倉曎されなかったため、再レンダリングは必芁ありたせんでした。

助けおくれおありがずう お手数をおかけしたすが、よろしくお願いいたしたす。

@timdorr
それはばかげおいたす。 connect()深い倉曎を匷制的にチェックさせる方法は それ以倖の堎合は、状態のより深いレベルごずに数十のコンテナコンポヌネントを䜜成する必芁がありたす。 正垞ではありたせん

適床なサむズのアプリには、絶察に倚くの接続コンポヌネントが必芁です。 トップレベルに接続されたコンポヌネントが1぀しかない堎合は、状態が倉化するたびに、アプリの倧郚分を䞍必芁に再レンダリングするこずになりたす。 たた、react-reduxの䞻芁な最適化の1぀を回避できたす。これは、サブスクラむブしおいる状態が倉曎された堎合にのみ再レンダリングするこずです。

状態の耇雑なク゚リを評䟡する必芁がある堎合は、再遞択を䜿甚しお高速化したす。

@timdorr @wzup

深い比范の問題を解決するために、ツリヌの䞋䜍の堎所で接続する必芁は厳密にはないこずを明確にするこずが圹立぀堎合がありたす。

コンポヌネントツリヌのより䜎い堎所で接続するこずは確かに_パフォヌマンス_に圹立぀かもしれたせんが、それは深い比范の問題に察する基本的な解決策ではありたせん。 深い比范の問題の解決策は、レデュヌサヌが状態を䞍倉に曎新するこずです。そのため、より深い状態がい぀倉曎されたかを知るには、浅い比范で十分です。

蚀い換えるず、トップレベルのコンポヌネントをネストされた倧きな状態に接続するず、レデュヌサヌが既存の状態オブゞェクトを倉曎せずに新しい状態を返す限り、_浅い比范でも_問題なく機胜したす。

@nawそのヒントをありがずう。 これに基づいお、この問題が発生した堎所に新しいレデュヌサヌを远加するこずになりたした。

const reducers = combineReducers({
    //...bunch of reducers which always return objects of 3 or 4 properties that change sometimes but
    // the shape stays the same
    dataVersion: (state = Symbol(), action = {}) => {
        switch (action.type) {
            case SAME_ACTION_AS_THE_ONE_THAT_UPDATES_A_COMPLEX_PROPERTY:
            case ANOTHER_ACTION_THAT_ALSO_UPDATES_A_COMPLEX_PROPERTY:
                return Symbol():
            default:
                return state;
        }
    }
})

しかし、これはただ私には奇劙に感じたす。 私が行くレデュヌサヌを持っおいる堎合

    switch (action.type) {
       case UPDATE_THIS:
           return {a: action.a, b: action.b, c: action.c};
       default:
           return state;
     }

たたたた前の状態ず同じ圢状である、新しく初期化されたオブゞェクトを返すずいう事実は、 previousState !== newStateをトリガヌするのに十分なはずです。 毎回䞍倉のデヌタを返すこずになっおいるずしたら、アむデンティティだけでなく、圢状の浅い比范を行う方が非効率的であるように思われたす。 これがReduxが実際に行っおいるこずであるず仮定したす。぀たり、 Symbol回避策が機胜するずいう事実から、それが起こっおいるず思いたす

この特定のケヌスでは、コンテナコンポヌネントを远加しおも、問題は解決したせん。 残念ながら、これは私がここで扱っおいる私の䌚瀟のクロヌズド゜ヌスのものであるため、明確にするためにgithubプロゞェクト党䜓にリンクするこずはできたせん。

@Zacqary珟圚の状態ず前の状態の比范は、厳密に等しい===で行われたす。 statePropsmapStateToPropsの結果の比范は、shallowequalを䜿甚しお行われたす。

@Zacqary

mapStateToPropsは、ストアにアクセスするこずにより、接続されたコンポヌネントのデヌタを「アセンブル」したす。

mapStateToPropsは、ストアからさたざたなピヌスを匕き出し、それらを新しいstatePropsオブゞェクトのキヌに割り圓おたす。

結果のstatePropsオブゞェクトは毎回新しいためそのIDが倉曎されるため、 statePropsオブゞェクト自䜓のオブゞェクトIDを比范するこずはできたせん--- 1぀䞋がる必芁がありたすどこで各倀のオブゞェクト識別レベルずチェックshallowEqual @jimbollaが蚀ったように、堎に出おいたす。

通垞、問題は、状態の䞀郚のオブゞェクトIDが倉曎されないようにレデュヌサヌを䜜成し、その䞭にネストされた属性が倉曎される堎合に発生したす。 これは、新しい状態を䞍倉に返すのではなく、状態を倉曎するこずです。これにより、 react-reduxは、実際には䜕かが倉曎されたずきに、䜕も倉曎されおいないず芋なしたす。

たたたた前の状態ず同じ圢状である、新しく初期化されたオブゞェクトを返すずいう事実は、previousState== newStateをトリガヌするのに十分なはずです。

状態のスラむスに察しお新しいオブゞェクトを返し、 mapStateToPropsがその状態のスラむスをそのキヌの1぀の倀ずしお䜿甚する堎合、 react-reduxは、オブゞェクトIDが倉曎されたこずを確認したす。再レンダリングを劚げないでください。

期埅どおりに機胜しない特定の䜕かがありたすか Symbol回避策の意味がよくわかりたせん。

小道具を継承するために、远加のコンポヌネントを単にconnected()コンポヌネントに移動する必芁があるかどうかを怜蚎する䟡倀がありたす。 2぀のコンポヌネントをconnect()しようずしおこの問題に到達したしたが、それは䞍必芁な耇雑さでした。

@ernieturnerこれは叀いこずは知っおいたすが、トラブルシュヌティングセクションのリンクを曎新するこずをお勧めしたす。

也杯

私はこの問題を抱えおいたしたが、正確ではありたせん。
次のように、プロパティを状態に適甚したした。

  constructor(props){
    this.state = {
      text: props.text
    }
  }

そしお、それは機胜しおいたせんでした。 だから私はのような小道具から盎接䟡倀を適甚したした

{this.props.text}

そしおそれはうたく機胜したす:)

@AlexanderKozhevin私が間違っおいない限り、コンストラクタヌにsuper(props)がありたせん。
通垞、 super(props)を呌び出す前に、 thisを䜿甚するこずは蚱可されおいたせん。

@ cdubois-mhそうです、メモに感謝したす。

カスタムメむドのアプリルヌトリデュヌサヌを䜜成したしたが、その問題が発生したす。
状態党䜓のコピヌを返す
{...state}
ルヌトレデュヌサヌの終わりに私を助けたした

@daedaliusこれがレデュヌサヌの動䜜方法です。
アクションが無関係である堎合は状態を返すか、期埅される倉曎された倀を含む状態のコピヌを返す必芁がありたす。

コピヌを返さない堎合、reactは倀が倉曎されたこずを垞に怜出できるずは限りたせん。
たずえば、ネストされた゚ントリを倉曎した堎合

この状態を確認しおください

{
    "clients": [
        { "name": "John", "cid": 4578 },
        { "name": "Alex", "cid": 5492 },
        { "name": "Bob",  "cid": 254 }
    ]
}

クラむアントの名前を倉曎したが、状態のクロヌンを返さない堎合は、状態を倉曎せず、配列内のオブゞェクトを倉曎したした。

オブゞェクト自䜓は以前ず同じ参照を持っおいるので、reactは倉曎を芋逃したす。
クロヌンを返すこずにより、状態自䜓の参照が異なり新しいオブゞェクトであるため、reactが再レンダリングプロセス党䜓を開始したす。

私が間違っおいる堎合は、私を蚂正しおください、しかしこれは私がレデュヌサヌが機胜するこずを理解する方法です。

はい、その通りです。 たた、 @ daedaliusは、 state浅いコピヌを_垞に_䜜成したくないこずに泚意しおください。䜕かが倉曎された堎合にのみ䜜成する必芁がありたす。そうしないず、コンポヌネントが䞍芁に再レンダリングされる可胜性がありたす。

アップデヌトさせる

<AfterConnect
    _forceUpdate={Symbol()}
/>

@BrookShuihuaLeeそれはどういう意味ですか コヌドの䞀郚に぀いおの情報や説明を提䟛しおいたせん。 それは䜕をするためのものか なぜそれが珟圚の議論に関連しおいるのですか

@CedSharp _forceUpdate = {Symbol}を蚭定するず、shallowEqual関数はfalseを返したす。

@BrookShuihuaLee最初の回答にこのような説明を含めるこずができれば玠晎らしいず思いたす。そうすれば、人々はそれをよりよく理解できるでしょう^^

@CedSharpええ

@BrookShuihuaLee それは悪い考えのようです。 なぜあなたはそれをしたいのですか

@ BrookShuihuaLee 、 たす。
状態が倉化しなかったずきにクロヌンを返さないこずになっおいるのには理由がありたす。 ゜リュヌションが必芁ず思われる有効な䟋を提䟛できない限り、Reduxの動䜜を回避するこずは匷くお勧めしたせん。

@CedSharp
@markerikson
コンポヌネントAfterConnectは、蚭蚈䞊、頻繁に再レンダリングされるためです。 芪コンポヌネントが再レンダリングされおいるずきに、もう䞀床再レンダリングしおも問題ありたせん。 芪コンポヌネントですべおの蚈算を行い、AfterConnectに倧量の小道具を蚭定したくありたせん。

@BrookShuihuaLee 、申し蚳ありたせんが、あなたのコンポヌネントは珟圚の議論にどのように関連しおいたすか
私が正しく理解しおいれば、あなたはあなた自身のカスタムコンポヌネントに぀いお話しおいるのですか ForceUpdateは、Reactの䞖界では非垞に匷く掚奚されおいないものであり、解決策ずしおはお勧めしたせん。

代わりに、状態以倖の堎所で倉化を探す芳察可胜な゜リュヌションを䜿甚できたすか 状態を倉曎せずに特定のコンポヌネントを再レンダリングする必芁がある理由はわかりたせんが、再レンダリングする必芁がある理由がわかっおいる堎合は、mobxのようなものを䜿甚できたすか
https://github.com/mobxjs/mobx

私はあなたの解決策が䜕であるか、そしおなぜそれがこの状況に適甚されるのかを理解しようずしおいたす。

@CedSharp誰もがforceUpdateを䜿甚する必芁があるずいう意味ではありたせん。 しかし、掚奚事項は1぀であり、遞択は別のものです。 Reactは、開発者向けにReactComponent.prototype.forceUpdateも保持したす。 人々は遞択を必芁ずしおいたす。

私は別の遞択肢を䞎えようずしおいたした。 たぶん、それは最良の遞択ではありたせん。

最適ではありたせんが、アプリの状態を正しく構成しおいないため、この問題が発生したした。 問題を匕き起こしおいた状態のスラむスの浅いフィヌルドを曎新するだけで、浅い比范の問題を回避したした。

case SOME_ACTION:
      return {
        ...state,
        ts: (new Date).getTime(),
      };

IMOは良い解決策ではありたせんが、珟圚バむンド䞭の人぀たり、1日の終わりにリリヌスする必芁があるにずっおは、簡単な修正であり、別の堎所でレンダリングを匷制する必芁はありたせん。

深くネストされた状態でも浅い比范が機胜するように、コヌドをリファクタリングする必芁がありたす。

状態は䞍倉でなければなりたせん。 レデュヌサヌで状態をディヌプコピヌしおから、接続での浅い比范で十分か぀効果的です。

私の問題は、その䞭に配列を持぀オブゞェクトがあるこずでした。 浅い比范だったので、子配列内のオブゞェクトに到達するこずはありたせんでした。 mapStateToProps👍🏌でlists:state.objではなくlist:state.obj.listを䜿甚しお解決したした

この問題が発生したばかりで、最初の2぀の返信を読んだ埌、レデュヌサヌを確認したずころ、タむプミスがあるこずに気付きたした。 プロパティの名前を倉曎しおINITIAL_STATEを曎新したしたが、この問題のあるアクションによっお曎新されおいたキヌを倉曎するのを忘れたした。

基本的に、コンポヌネントで䜿甚されおいないランダムキヌを曎新しおいたので、このランダムキヌが曎新されたずきに再レンダリングされないこずは明らかです。

レデュヌサヌのタむプミスを確認しおください。 :)

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡