2016-07-07 14 views
0

私はこれがProtected HOCを持ってはならないと言われるとき、ラップされたコンポーネントはまだレンダリングします。その目的は、ユーザーが認証されたときにのみWrappedComponentをレンダリングすることです。それ以外の場合はAuthenticateComponentをレンダリングする必要があります(通常はログインコンポーネント)。コンポーネントの還元状態がそれが

import React from "react" 

const PROPTYPES = { 
    authenticated: React.PropTypes.bool.isRequired, 
} 
export default (WrappedComponent, AuthenticateComponent) => { 
    let Protected = (props) => (
    props.authenticated 
    ? <WrappedComponent {...props}/> 
    : <AuthenticateComponent {...props}/> 
) 
    Protected.propTypes = PROPTYPES 
    return Protected 
} 

小道具は、接続されているReduxのコンテナコンポーネント

const AccountContainer = ({ children }) => (
    <div>{children}</div> 
) 
const select = state => state.account 
export default connect(select, { refreshUser, logout })(Protected(AccountContainer, LoginContainer)) 

から来た私のaccount減速機は、次のようになります

function authenticated(state = false, action) { 
    switch (action.type) { 
    case actions.START_SIGNUP_SUCCESS: 
    case actions.LOGIN_SUCCESS: 
     return true 
    case actions.LOGIN_ERROR: 
    case actions.START_SIGNUP_ERROR: 
    case actions.LOGOUT_SUCCESS: 
     return false 
    default: 
     return state 
    } 
} 

... 

export default combineReducers({ 
    authenticated, 
    access_token, 
    loggingIn, 
    user, 
    error, 
}) 

LOGOUTアクションが設定されている場合ことを今起こりますstate.account.authenticatedプロパティはfalseに設定されていますが、まだWrappedComponentがレンダリングされています。それはaccountのさまざまな他のプロパティにアクセスし、それらもすべて既にクリアされており、コンポーネントはチェックしたり期待したりしません。 は、レンダリングされるとaccountの状態がまだauthenticatedであることを前提としています。

どのような競合状態になるのだろうか?

答えて

1

私はコードを見ることなく知ることができませんが、あなたのレデューサーは状態を変化させるようです。減速機は決して状態を変えるべきではありません。代わりに、適切なプロパティで新しい状態を作成する必要があります。

競合状態やその他の異常を防ぐことがそのポイントです。

React Reduxは、あなたがここで見ている問題の種類を防ぐために非常に注意深く設計されています。あなたはReduxのルールを守る必要があります。主なものは、減速器純粋な機能でなければならないことです。

レデューサーが古い状態を変更してその状態を返す場合、Reduxは状態を変更したことを簡単に確認できません。実際、変更は行われていないとみなされます。このように何も再レンダリングされません。

編集:

あなたの減速が、私はaccount減速が他の場所で使用されているかを確認することができないにもかかわらず、正常に見える、私はそれが同様に罰金だと仮定します。

私が問題と思うのは、コンポーネントが実際にレンダリングされないことですが、レンダリングメソッドはまだLOGOUTに呼び出されます。何が起こっているのか、そのサブコンポーネントがそのようなレンダリングを要求した場合、Reactはサブコンポーネントをうまくレンダリングします。そして、connectstoreのアップデートに繋がり、それが起こるようになったので、これは起こっていることです。

すると、あなたの状態が変化し、WrappedComponentconnectが再評価されますpropsmapStateToPropsを呼び出すことによって、それは、これらの小道具は(原因もはやログインされており、このデータは、したがって、それは以前よりも異なることに)変化していることがわかります。 Connectは、ReactにWrappedComponentの再レンダリングを指示します。それで反応が起こります。あなたのrenderメソッドは、ユーザーがログインしているときにのみ使用される無効なデータであるため、渡されるデータに問題がある可能性があります。

解決方法は、単純にレンダリングをダミー<div/>。このdivは、仮想DOM要素であり、実際にはDOMには入れません。要素をキャッシュし、DOMの更新をバッチ処理します。それで、ReactはそれをDOMにマージする前にWrappedComponent全体を整理してしまいます。残念ながら、すでに新しいバージョンがレンダリングされた後です。

Reduxにはコンポーネントの概念がないため、考慮することはできませんが、Connectは作成された順序でストアにサブスクライブしているため、実際にはここでの原因となるのは、Connectと組み合わせたReduxです。ストアは加入した順にコンポーネントに通知します。

最後の順序は、レンダリング順序とマウント順序によって異なり、多くのコンポーネントがこの順序を決定する役割を果たします。それは単に安定していないので、数えてはならない。あなたが接続されているコンポーネントを構築するとき

、あなたのmapStateToProps取るために任意の有効な状態を書き込み、ターゲットコンポーネントのものから有効小道具をコンパイルすることを確認してください。ダミー値を追加する場合でも、コンポーネント自体を変更して有効なものにする場合でも、これらのコンポーネントが表示されることはない場合でも、有効なすべての状態を有効なプロンプトに解決することが重要です。これにより、実際に有効な状態(ログアウトされた状態が有効な状態)から生じる不正な小道具によるエラーを防ぐことができます。

もちろん、決して発生してはならない無効な状態に対処する必要はありません。

+0

私のレデューサーコードで私の質問を編集しました。お元気ですか? – philk

関連する問題