2016-04-12 10 views
1

リアクタ・ルータ1.xを指し示すものが見つかった場合は、重複しないでください。この問題に関して私がStackOverflowで読んだ答えは廃止された構文を使用しています。リアクタ・ルータ2.0:ログインから子供にユーザ名を渡す

私はベース( "/")パスに非常に単純なログインページがあり、ログインした後、ユーザーのユーザー名はすべての子に小道具を介して渡されます(後続のすべてのAPI呼び出しでパラメータとして使用されることになります)。

render((
    <Router history={hashHistory}> 
    <Route path="/" component={App}> 
     <IndexRoute component={Login} /> 
     <Route path="/feed" component={Feed} /> 
     <Route path="/search" component={Search} /> 
    </Route> 
    </Router> 
), document.getElementById('react-content')); 

App.jsを::

問題は、それは、ルータが反応など

ルートをroutecomponent以外<Route>タグに追加小道具を認識していないようです

var App = React.createClass({ 
    getInitialState: function() { 
    return {username: ''}; 
    }, 
    updateUser: function(name) { 
    this.setState({username: name}); 
    }, 
    render: function() { 
    return React.cloneElement(this.props.children, 
     {username: this.state.username, assignUser: this.updateUser} 
    ); 
    } 
}); 

Login.js:

var Login = React.createClass({ 
    contextTypes: { 
    router: React.PropTypes.object.isRequired 
    }, 
    getInitialState: function() { 
    return {user: this.props.username}; 
    }, 
    userLogin: function(value) { 
    setTimeout(this.props.assignUser(value), 0); 
    this.context.router.push('/feed'); 
    }, 
    render: function() { 
    return (
     <div className="loginBody"> 
     <div className="formDiv"> 
      <form className="loginForm" onSubmit={this.userLogin(value)}> 
      <select value="user1"> 
       <option value="user1">User 1</option> 
       <option value="user2">User 2</option> 
       <option value="user3">User 3</option> 
       <option value="user4">User 4</option> 
      </select> 
      <button type="submit">Submit</button> 
      </form> 
     </div> 
     </div> 
    ); 
    } 
}); 

username<Feed><Search>のコンポーネントにどのように渡されるかわかりません。これらが<Login>コンポーネントの子でない場合、どのように継承を確立しますか?

+1

あなたのルートの設定で二度 'Login'を持っている..私はあなたが取り除くべきだと思います外部のものの 'Login'を' App'の子として保ちます。こうすることで、関数を介してAppに値を簡単に渡し、 'cloneElement'を使って他のルートに戻すことができます。どちらか、それともreduxを使うのですか? – azium

+0

@ azium:あなたが提供してくれたガイダンスの一部を統合して、私の質問に文脈を追加しました。しかし、それでもユーザ名は ''に設定されておらず、API呼び出しに必要なユーザ名は ''と ''にどのように渡されるかわかりません。 – zahabba

答えて

3

別のコンポーネントにユーザー名を表示するためにサインインするときに、アプリケーションを読み込むことから、これを時系列的にフォローしてみましょう。

私たちが始まる前のこと - すべてのアプリの状態はAppになります。他のすべてのコンポーネントは、小道具(App状態&関数)として渡された値のみを受け取ります。 、あなたのルートの設定がthis.props.children

  • <App />負荷を移入する負荷<App />と一致<Login />を言う

    • { username: '' }
    • の初期状態を設定します。

      1)誰かがルートパス/であなたのサイトを訪問します

    • アプリのrenderが呼び出され、その子(Login)をクローニングしてusernameおよびupdateUserを小道具として使用します。私はここに若干の変更をするだろう:

      render() { 
          // Children helper here because React children can be object or array 
          var children = React.Children.map(this.props.children, function (child) { 
          return React.cloneElement(child, { 
           username: this.state.username, 
           updateUser: this.updateUser // use same fn name for clarity 
          }) 
          }) 
      
          // give your root component some context/selection 
          return <div id="app">{ children }</div> 
      } 
      

    2)ユーザがログインフォーム

    • を提出する今すべては<App />で管理される予定であることを私たちがするLoginをダウン削ることができます関数ではなく、関数である。

      var selectEl  
      
      var Login = function (props) { 
          return (
          <form 
           className="loginForm" 
           onSubmit={function (event) { 
           event.preventDefault() // prevent page reloading 
           props.updateUser(selectEl.value) 
           }} 
          > 
           <select 
           defaultValue="user1" 
           ref={ function (node) { selectEl = node } } 
           > 
           <option value="user1">User 1</option> 
           </select> 
           <button type="submit">Submit</button> 
          </form> 
      ) 
      } 
      

    ほとんどここで注意すべき点(私はこの例では、いくつかを削除するつもりです):それは、初期状態やライフサイクルの機能を持っていないので、これは単なる関数である

    • 空の変数が先頭に宣言されています。選択要素のrefコールバック関数が呼び出されると、ノードはこの変数に格納されます。
    • defaultValue is (valueの代わりに)あなたの選択に使用されます。スイッチオプション
    • を引数に渡して新しい値を得るには、onSubmitにコールバック関数を宣言する必要があります。あなたはちょうどあなたがあなたのフォームを送信する場合さて、あなたの選択の値は、あなたのApp年代に上がるだろう

    機能(ない関数の戻り値)であることをupdateUser(value)onSubmitので、ニーズを書き込むことはできませんupdateUser関数。ここではリダイレクトをしたいと思うかもしれません。したがって、リダイレクトが存在する場合は、updateUser関数がURLを取得するように機能を補強します。

    updateUser: function(name, url) { 
        this.setState({username: name}) 
        if (url) this.context.router.push(url) 
    }, 
    

    これはあなたが必要とするすべてのもの...そして、あなたの他のコンポーネントの内部で、this.props.usernameが移入されますする必要があります:

    var Feed = function (props) { 
        return <div>{ props.username }</div> 
    } 
    
  • +0

    壮大な答え。 contextTypeの定義にもかかわらず、 'this.context'で定義されていないエラーが発生しましたが、私はそれを理解します。 – zahabba

    +0

    :すべての"コンポーネント "は実際にはではありません。しかし、機能?私はどのように他のすべてのコンポーネントを今呼び出すのだろうと思っています、そして、どのくらい再構成する必要がありますか(フィードは254行の長さです、例えばコンポーネントとして)。 – zahabba

    +0

    react-routerあなたは使用していますが、 'browserHistory.push'を使ってコンテキストを追加する必要を避けることができます(2.0xで)。Re:コンポーネント、React 'components'を書く方法は2つあります:1)React.createClassを呼び出し、2) 'render'関数です。どちらの方法も有効ですが、単純に関数をレンダリングするコンポーネントは、より簡単に推論することができます。これは、状態ツリーとビジネスロジックをコンポーネントツリーにプッシュするのに役立ちます。それはあなたの質問に答えますか? – azium

    関連する問題