2016-11-25 9 views
0

ボタンがクリックされたときに登録またはログインルートにリダイレクトしたいのは、ボタンがモーダルであることを示しているからです。親コンポーネントにshowModal関数があります。つまり、子コンポーネント(Nav)に継承されているAppです。 onClickイベントの処理を担当する私のshowModal関数がAppコンポーネントにあるので、私はそこでルータコンテキストを使用しようとしましたが、私はundefinedを取得しています。ルータコンテキストを使用できません[react-router v4]

は、ここに私のコード私は反応し、ルータのV4を使用しています

index.js

ReactDOM.render(
    <Provider store={createStoreWithMiddleware(reducers)}> 
    <ConnectedIntlProvider> 
     <Router> 
     <App /> 
     </Router> 
    </ConnectedIntlProvider> 
    </Provider> 
    , document.querySelector('.app')); 

class App extends Component { 
    constructor(props, context) { 
    super(props, context); 
    console.log('context', context); 
    this.state = { show: false }; 
    } 

    showModal(e) { 
    e.preventDefault(); 
    this.setState({ show: true }); 
    this.context.router.transitionTo(e.target.href); 
    } 

    hideModal() { 
    this.setState({ show: false }); 
    } 

    render() { 
    return (
     <div className="container-fluid"> 
      <Nav 
      showModal={(e) => this.showModal(e)} 
      hideModal={() => this.hideModal()} 
      show={this.state.show} 
      onHide={() => this.hideModal()} 
      /> 
     </div> 
     ); 
    } 
} 

App.contextTypes = { 
    router: React.PropTypes.object 
}; 



const Nav = (props) => (
    <div> 
     <nav className="navbar navbar-default"> 
     <div className="container-fluid"> 
      <div className="navbar-header"> 
      <a className="navbar-brand" href=""> 
       <img 
       alt="Brand" 
       className="img-responsive" 
       src={logo} 
       role="presentation" 
       /> 
      </a> 
      </div> 
      <div className="collapse navbar-collapse" id="collapse-1"> 
      <ul className="nav navbar-nav navbar-right nav-social-icon"> 
       <li className="dropdown"> 
       <a 
        href="" 
        className="dropdown-toggle" 
        data-toggle="dropdown" 
       > 
        ES 
        <span className="caret" /> 
       </a> 
       <ul className="dropdown-menu" style={{ color: '#000', fontWeight: 'bold' }}> 
        <li onClick={() => props.selectedLocale('en')}> 
        en 
        </li> 
        <li onClick={() => props.selectedLocale('es')}> 
        es 
        </li> 
       </ul> 
       </li> 
       <li className="btn-group regLog"> 
       <button 
        className="btn btn-default" 
        onClick={props.showModal} 
       > 
        <Link to={{ pathname: '/signup' }}> 
        {props.intl.formatMessage({ id: 'nav.registration.text' }) } 
        </Link> 
       </button> 
       <button 
        onClick={props.showModal} 
        className="btn btn-default" 
       > 
        <Link to={{ pathname: '/login' }}> 
        {props.intl.formatMessage({ id: 'nav.login.text' }) } 
        </Link> 
       </button> 
       {props.show ? 
        <ModalForm 
        show={props.show} 
        onHide={props.onHide} 
        /> : <span /> 
       } 
       </li> 
      </ul> 
      </div> 
     </div> 
     </nav> 
    </div> 
); 


class ModalForm extends Component { 
    render() { 
    const { show, onHide, intl } = this.props; 
    return (
     <Modal 
      {...this.props} 
      show={show} 
      onHide={onHide} 
      dialogClassName="custom-modal" 
     > 
      <Modal.Header closeButton> 
      <Link to='/login' className="logTitle"> 
       <Modal.Title id="contained-modal-title-lg"> 
       {intl.formatMessage({ id: 'nav.login.text' })} 
       </Modal.Title> 
      </Link> 
      <Link to='/signup' className="logTitle"> 
       <Modal.Title id="contained-modal-title-lg"> 
       {intl.formatMessage({ id: 'nav.registration.text' })} 
       </Modal.Title> 
      </Link> 
      </Modal.Header> 
      <Modal.Body> 
      <Match pattern='/login' component={Login} /> 
      <Match pattern='/signup' component={Signup} /> 
      </Modal.Body> 
     </Modal> 
    ); 
    } 
} 

です。あなたは自分の親コンポーネントでこれを追加し、その後

<Route path="users" component={User}> 
    <Route path="login" component={Login}/> 
</Route> 

のような子ルートを追加する必要が3つのもの

最初に行う必要があり

答えて

1

を使用して、このモーダルオープンモーダルボックスにあなたのコードは少し奇妙です。コンポーネントツリーのルートの近くには、<___Router>Browser,HashまたはMemoryのいずれか)しかないはずです。

ReactDOM.render((
    <BrowserRouter> 
    <App /> 
    </BrowserRouter> 
), document.getElementById('root')) 

routerコンテキストは<Router>構成要素の子要素にのみ利用可能です。 <Router><App>コンポーネントの子であるため、<App>routerコンテキスト変数にアクセスできません。

注:私の回答は、コンポーネントツリーのルートを含まないコードに基づいています。別の<Router>が上に定義されている場合は、あなたの質問へのより良い回答に役立つコードに記述する必要があります。

+0

申し訳ありません私は反応ルータv4を使用しており、ルートコンポーネントに1つのルータコンポーネントを持つ必要はありません。 – Serenity

+0

ルータはルートである必要はありませんが、あなたのアプリケーション内に1台のルータしか置いてはいけないという点が残っています。 –

+0

私はそれを理解しています。これで私を助けてくれますか?私はApp.jsでルータコンポーネントを使用する必要がありますか? – Serenity

0

、これは、URLから自動的に成分を検出し、応じてコンポーネントをレンダリングしますそれに。

{this.props.children} 

これで、ログインモード用に別のコンポーネントを作成する必要があります。あなたが複数の<Router>のコンポーネントを使用しているため、これ

componentDidMount: function(){  
    $('#login-modal').modal('show');  
}, 
+0

OPの質問は、v2/3とは異なるAPIを使用しており、もはや 'コンポーネントを持たず、レンダリングに' this.props.children'も依存していませんでした。 –

+0

その反応ルータv4 – Serenity

関連する問題