2017-02-21 4 views
1

ページを表すReactコンポーネントがあります。ユーザーは、何らかの状態がない限り、ページにアクセスしないでください。リダイレクトコードはどこに置く必要がありますか?

warning.js:36警告:SETSTATE(...):

class BoxScreen extends Component { 

    constructor(props) { 
    super(props); 

    if (Object.keys(this.props.boxState.current).length === 0) { 
     browserHistory.push('/secured/find') 
    } 

は、私は、このメッセージが表示されます:私は状態が欠落している場合react-routerユーザーをリダイレクトを持って、次の書い更新できません。既存の状態遷移中(renderまたは他のコンポーネントのコンストラクタ内など)。レンダリング方法は、小道具と州の純粋な機能でなければなりません。コンストラクタの副作用はアンチパターンですが、componentWillMountに移動することができます。

[OK]をので、私はcomponentWillMountに私のリダイレクトコードを移動します:

class BoxScreen extends Component { 
    ... 

    componentWillMount() { 
    if (Object.keys(this.props.boxState.current).length === 0) { 
     browserHistory.push('/secured/find') 
    } 
    } 

    render() { 
    // Don't want this executed or else I'll need to pollute it with null guards... 
    } 
} 

しかし、問題は、上記の間違い希望されていない、と呼ばれているからrenderを停止しないということです。これを置くための最も適切な場所はどこですか?私はコンポーネントレンダリングを短絡し、リダイレクトを実行できますか?

答えて

1

あなたはそれを達成するために反応し、ルータのonEnter小道具を使用することができます。

function checkAuthenticated(nextState, replace) { 
    if (!SOME_CONDITION) { 
    replace('/secured/find') 
    } 
} 

<Route ... onEnter={checkAuthenticated} /> 

しかし、私はあなたがこの方法でコンポーネントの小道具にアクセスすることはできませんと信じています。他の方法で状態を把握しておく必要があります。 Reduxを使用している場合は、redux-routerを使って店舗に行くことができます。

あなただけの内部<Redirect/>コンポーネントをreact-router年代を使用Enter/leave hooks documentation

1

を確認することができますが、私はそれと互換性のある、あなたのソリューションを提供しますので、私はV4を使用しています、それを達成するためにレンダリングします。

import {Redirect} from 'react-router-dom'; 
class BoxScreen extends Component { 
    ... 
    render() { 
     return this.props.condition ? 
        <ActualComponent /> : <Redirect to="/someGuardLink">; 
    } 
} 

<ActualComponent />をコンポーネントJSXに置き換えてください。これはうまくいくはずです。あなたのコンポーネントはまだマウントされ、レンダリングされますが、その後、あなたは他のリンクにリダイレクトされます。これはそれを行う公式な方法です。

+0

また、コンポーネントのコンストラクタからレンダリングへのフローを中断しないように、Lucasのアプローチを使用してコンポーネントのライフサイクルをまったく入力しなくてもよいし、一度入力すると中断しないでください。より良い方法は、コンポーネントをnullガードでレンダリングさせ、 'this.props'をチェックする' componentDidMount() 'の中で' this.history.push( '/ someGuardLink') 'を実行することです。 – smishr4

関連する問題