2014-10-03 2 views
60

Я делаю свой первый шаг в ReactJS и пытаюсь понять связь между родителем и детьми. Я делаю форму, поэтому у меня есть компонент для стилей полей. А также у меня есть родительский компонент, который включает в себя поле и проверку его. Пример:Метод вызова ReactJS

var LoginField = React.createClass({ 
    render: function() { 
     return (
      <MyField icon="user_icon" placeholder="Nickname" /> 
     ); 
    }, 
    check: function() { 
     console.log ("aakmslkanslkc"); 
    } 
}) 

var MyField = React.createClass({ 
    render: function() { 
... 
    }, 
    handleChange: function(event) { 
//call parent! 
    } 
}) 

Есть ли способ сделать это. И моя логика хороша в реакции «мира»? Спасибо за ваше время.

ответ

87

Для этого вы передаете обратный вызов как свойство до ребенка из родителя.

Например:

var Parent = React.createClass({ 

    getInitialState: function() { 
     return { 
      value: 'foo' 
     } 
    }, 

    changeHandler: function(value) { 
     this.setState({ 
      value: value 
     }); 
    }, 

    render: function() { 
     return (
      <div> 
       <Child value={this.state.value} onChange={this.changeHandler} /> 
       <span>{this.state.value}</span> 
      </div> 
     ); 
    } 
}); 

var Child = React.createClass({ 
    propTypes: { 
     value:  React.PropTypes.string, 
     onChange: React.PropTypes.func 
    }, 
    getDefaultProps: function() { 
     return { 
      value: '' 
     }; 
    }, 
    changeHandler: function(e) { 
     if (typeof this.props.onChange === 'function') { 
      this.props.onChange(e.target.value); 
     } 
    }, 
    render: function() { 
     return (
      <input type="text" value={this.props.value} onChange={this.changeHandler} /> 
     ); 
    } 
}); 

В приведенном выше примере, Parent называет Child со свойством value и onChange. Child в свою очередь привязывает обработчик onChange к стандарту <input /> и передает значение до Parent обратного вызова, если он определен.

В результате changeHandler метод Parent «ы вызывается с первым аргументом является строковое значение из <input /> поля в Child. В результате состояние Parent может быть обновлено с этим значением, в результате чего элемент родительского элемента <span /> обновится с новым значением при вводе его в поле ввода Child.

+0

Спасибо много, что это именно то, что мне было нужно. – KaronatoR

+7

Я думаю, вам нужно связать родительскую функцию, прежде чем передать ее дочернему: '' – o01

+12

@ o01 no you не потому, что я использую 'React.createClass', который автоматически связывает все методы компонентов. Если бы я использовал классы React es6, вам нужно было бы привязать его (если бы вы не были автоматически привязаны к конструктору, что многие люди делают в эти дни, чтобы обойти это). –

2

Вы также можете сделать это с обычаем яваскрипта события, JQuery пример:

var YourComponent = React.createClass({ 

    componentDidMount: function(){ 

     // Register event (the name is just an example of namespacing) 
     $(document).on("ReactComponent:YourComponent:myCustomMethod", this.myCustomMethod); 
    }, 

    myCustomMethod: function(){ 

     // code 
    }, 

    render: function(){ 
     return (
      // jsx 
     ) 
    } 
}); 

// Trigger event from everywhere 
$(document).trigger("ReactComponent:YourComponent:myCustomMethod"); 

Помните, чтобы ограничить использование этого решения для «статический» Реагировать компоненты как можно больше, чтобы избежать слишком большого числа зарегистрированных событий что вы можете забыть отменить регистрацию.

+0

Спасибо. Я не уверен, что вложенный компонент - хороший дизайн, но это то, что у меня есть. Таким образом, распространение состояния через уровни становилось болью. – jbsmoove

11

Вы можете использовать любые родительские методы. Для этого вы должны отправить эти методы от своего родителя к себе, как к любому простому значению. И вы можете одновременно использовать много методов от родителя. Например:

var Parent = React.createClass({ 
    someMethod: function(value) { 
     console.log("value from child", value) 
    }, 
    someMethod2: function(value) { 
     console.log("second method used", value) 
    }, 
    render: function() { 
     return (<Child someMethod={this.someMethod} someMethod2={this.someMethod2} />); 
    } 
}); 

и использовать его в ребенка, как это (для любых действий или в каких-либо методов ребенка):

var Child = React.createClass({ 
    getInitialState: function() { 
     return { 
     value: 'bar' 
     } 
    }, 
    render: function() { 
     return (<input type="text" value={this.state.value} onClick={this.props.someMethod} onChange={this.props.someMethod2} />); 
    } 
}); 
+0

Спасибо, спасибо. @Vitaliy –

+1

Блестящий ответ. Не думаю, что вы могли бы передавать методы как реквизиты, подобные этому, я использовал ссылки для этого! –