2017-05-17 9 views
0

私はReactを初めて使用し、親からの2レベルの子構造を持つシナリオに遭遇しました。レベル2では、子コンポーネントの動的リストがあり、各子には関連するチェックボックスがあります。だから私はこの子のonChangeイベントの親にいくつかのデータ(果物の名前とIDを想定したもの)を渡すのですか?以下は子コンポーネントの親に引数を2レベルで渡す方法

+0

:帽子はここにいくつか例を挙げます(データは親の状態で保存され、その後、あなたはsetStateが含まれている機能を渡すことができると仮定して)

を親の状態を変更することができます問題をより正確に説明するためのサンプルです。その答えを見つけると役立ちます。 –

+0

親から変更時に親のローカル状態を設定し、更新された状態を使用してロジックを実行するレベル2の子(レベル1の子を介して)に関数を渡すことができます。 – char

答えて

0

が、私は関数を定義した場合に必要な機能に解釈されるべきである なアクションしている私のアクションクラスが呼ばれている。ここ

import Dispatcher from "./Dispatcher.jsx"; 
export function createTodo(text) 
{ 

Dispatcher.dispatch(
{ 

type: "CREATE_TODO", 
text 

} 
); 


} 

がディスパッチャによってからアクションが供給された私の店コンポーネントです

import {EventEmitter} from 'events'; 
import React from 'react'; 
import Dispatcher from "./Dispatcher.jsx"; 
class TodoStore extends EventEmitter 
{ 
constructor() 
{ 
super(); 
this.todos=[ 



     ] 
      } 

      createNewTodo(text) 
      { 

       const id=Date.now(); 
       this.todos.push({ 
        id, 
        text, 
        company:"Ibm" 
       }); 
       this.emit("change"); 

      } 

      getAll() 
      { 
      return this.todos; 
      } 

      handleActions(action) 
      { 
       console.log("todostore receied an action",action); 
       switch(action.type) 
       { 
       case "CREATE_TODO": 
{ 

        this.createNewTodo(action.text); 
       } 


       } 



      } 


} 

ここでは、todoActionsコンポーネントのcreateTodo(text)関数を呼び出すFeaturedクラスがあります。

アクションがtodoActionsクラスで発生し、ディスパッチャーがそのアクションをディスパッチし、ストアコンポーネントのイベントエミッターのイベント変更にchangeイベントが発生し、このイベントがFeaturedコンポーネントにキャッチされ、このクラスに必須の引数が渡されます。

import React from 'react'; 
import { Link } from "react-router"; 
import {Button, IconButton} from 'react-toolbox/lib/button'; 
import Input from 'react-toolbox/lib/input'; 
import Todo from "./Todo.jsx"; 
import TodoStore from "./Store.jsx"; 
import injectTapEventPlugin from 'react-tap-event-plugin'; 
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 
import RaisedButton from 'material-ui/RaisedButton'; 
import * as todoActions from "./todoActions.jsx"; 





class Featured extends React.Component { 
    constructor() 
    { 

     super(); 

     this.state= 
     { 
     todos:TodoStore.getAll() 


     } 

    } 
    componentDidMount() 
    { 


    alert("after") 
    } 
    componentWillMount() 
    { 
     alert("before") 


     TodoStore.on("change",()=>{ 
      this.setState({ 
       todos:TodoStore.getAll() 
      }); 
     }); 
    } 
    createTodo() 
    { 

     todoActions.createTodo(Date.now()); 

    } 
    reloadTodo() 
    { 

     todoActions.reloadTodo(); 

    } 
    render() { 



     return (
     <MuiThemeProvider> 
     <div> 






     <h1>Featured</h1> 
     <Button label='Create' accent onClick={this.createTodo.bind(this)}/> 

     <table> 
     <tbody>{this.state.todos.map((todo, i) => <Todo key={i} todos= {todo} />)}</tbody> 
    </table> 
     </div> 
     </MuiThemeProvider> 
    ); 
    } 
} 


export default Featured; 
0

1つの方法は、コンポーネントを小道具としてコールバックを移送することです。最終child2のでは

render() { 
    return <Child2 handler={this.props.handler}/> 
} 

をあるとして、あなたが今ハンドラをインストールすることができ、レンダリング、レンダリングCHILD1のでは

//keep descriptive name so you can remember later on 
handleChangeInChild2(event) { 
    console.log("name:", event.target.name, ", val=", event.target.value) 
    //do your stuff 
} 

render() { 
    //sending the handler function to first child as a callback 
    return <Child1 handler={this.handleChangeInChild2.bind(this)}/> 
} 

小道具から選ぶとCHILD2に送信:

親コンポーネントのように、あなたのハンドラを作成INPUT

render() { 
    return <input type="checkbox" onChange={this.props.handler}/> 
} 
0

親から子への関数として関数を渡す必要がありますあなたには、いくつかのコードを使用することができる場合

class Parent extends React.Component { 
    constructor(props) { 
    this.state = { 
     data: {} 
    }; 
    this._transferData = this._transferData.bind(this); // Don't forget to bind the function to the component 
    } 

    _transferData(value, checked) { 
    /* 
     This is the function that accept values and 
     pass it to the state 
    */ 
    let data = {...this.state.data}; 
    data[value] = checked; 
    this.setState({ 
     data: data 
    }); 
    } 

    render() { 
    return (
     <Child1 onChange={this._transferData} /> 
     {/* The parent passes _transferData as a props for Child1 */} 
    ) 
    } 
} 

class Child1 extends React.Component { 
    render() { 
    return (
     <Child2 onChange={this.props.onChange} /> 
     {/* Child2 passes the passed function from Parent as a props (again) for Child2 */} 
    ) 
    } 
} 

class Child2 extends React.Component { 
    constructor(props) { 
    this.state = { 
     checked: false 
    }; 
    this._handleChange = this._handleChange.bind(this); // Don't forget to bind the function to the component 
    } 

    _handleChange(event) { 
    this.setState({ 
     checked: event.target.checked 
    }); 
    /* 
     Then Child2 uses the function to update the Parent's state 
    */ 
    this.props.onChange(event.target.value, event.target.checked); 
    } 

    render() { 
    return (
     <form> 
     <input 
      type="checkbox" 
      name="fruit" 
      value="Apple" 
      checked={this.state.checked} 
      onChange={this._handleChange} 
     /> I have an apple 
     </form> 
    ) 
    } 
} 
関連する問題