Метод батьківського виклику ReactJS


140

Я роблю перший крок у 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!
    }
})

Чи можна це зробити. І чи хороша моя логіка в реакції "світу"? Дякую за ваш час.

Відповіді:


154

Для цього ви передаєте зворотний виклик як властивість, передану дитині від батьків.

Наприклад:

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зворотного виклику 's, якщо він визначений.

У результаті Parentвикликується changeHandlerметод 's , причому перший аргумент є значенням рядка з <input />поля в Child. Результат полягає в тому, що стан Parent's може бути оновлений цим значенням, в результаті чого батьківський <span />елемент оновлюється новим значенням під час введення його в Childполе введення.


15
Я думаю, вам потрібно зв’язати батьківську функцію, перш ніж передавати її дитині:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
— 0101

19
@ o01 ні, ви цього не робите, тому що я використовую, React.createClassяке автоматично пов'язує всі компоненти компонентів. Якби я використовував класи React es6, тоді вам потрібно було б прив’язати його (якщо тільки ви не автозв’язували в конструкторі, що багато людей роблять в ці дні, щоб обійти це)
— Майк Драйвер

1
@MikeDriver Я бачу. Я не знав, що це обмежено випадками, що використовують ECMAScript 6 класів (що я є). Також не знали, команда React рекомендує автоматичне прив'язування в конструкторі.
— o01

1
Я не знаю, чи рекомендують вони це, але, здається, це досить звичайна річ, яку я бачу. Для мене більше сенсу, ніж вкладати прив'язку всередині потоку візуалізації, тому що .bindповертає нову функцію, тому в основному ви створюєте нову функцію щоразу, коли запускаєте візуалізацію. Це, мабуть, добре, але якщо ви пов'язуєте в конструкторі, ви робите це лише один раз за методом компонентів при створенні інстанцій, а не за кожним візуалізацією. Це збирання азоту ... але, гадаю, технічно приємніше!
— Водій Майка

1
@ DavidLy-Gagnon добре, у прикладі це може бути невизначено, оскільки я не додав isRequired на propType. Але так, ви можете це зробити або просто перевірити, чи це замість нього визначено чи ні.
— Водій Майка

52

Ви можете використовувати будь-які батьківські методи. Для цього вам слід надіслати такі методи від свого батька дитині, як будь-яке просте значення. І ви можете використовувати багато методів від батьків одночасно. Наприклад:

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} />);
    }
});

1
Блискуча відповідь. Не маю ідеї, що ви могли б передати методи, як реквізит, як це, я використовував рефлекси для цього!
— Пол Редмонд

1
Я отримав зворотний виклик, щоб викликати дитину, але там this.propsу зворотному дзвінку стає undefined.
— khateeb

Ви повинні надіслати цей зворотній дзвінок від батька до дитини (спробуйте зв’язати цей зворотний дзвінок this)
— Віталій Андрусишин

Привіт, Валентин Петков. Ласкаво просимо!
— Віталій Андрушишин

39

Оновлення 2019 року з реагуванням 16+ та ES6

Опублікування цього повідомлення, оскільки React.createClassзастаріло з версії 16 реагування, і новий Javascript ES6 дасть вам більше переваг.

Батьківський

import React, {Component} from 'react';
import Child from './Child';
  
export default class Parent extends Component {

  es6Function = (value) => {
    console.log(value)
  }

  simplifiedFunction (value) {
    console.log(value)
  }

  render () {
  return (
    <div>
    <Child
          es6Function = {this.es6Function}
          simplifiedFunction = {this.simplifiedFunction} 
        />
    </div>
    )
  }

}

Дитина

import React, {Component} from 'react';

export default class Child extends Component {

  render () {
  return (
    <div>
    <h1 onClick= { () =>
            this.props.simplifiedFunction(<SomethingThatYouWantToPassIn>)
          }
        > Something</h1>
    </div>
    )
  }
}

Спрощена дитина без громадянства як константа ES6

import React from 'react';

const Child = () => {
  return (
    <div>
    <h1 onClick= { () =>
        this.props.es6Function(<SomethingThatYouWantToPassIn>)
      }
      > Something</h1>
    </div>
  )

}
export default Child;

Бачачи 4 пробіли замість 2 у ES6 JS, мені сумно: '(
— Bataleon

3

Передайте метод від Parentкомпонента донизу як propваш Childкомпонент. тобто:

export default class Parent extends Component {
  state = {
    word: ''
  }

  handleCall = () => {
    this.setState({ word: 'bar' })
  }

  render() {
    const { word } = this.state
    return <Child handler={this.handleCall} word={word} />
  }
}

const Child = ({ handler, word }) => (
<span onClick={handler}>Foo{word}</span>
)

2

Використання функції || компонент без громадянства

Батьківський компонент

 import React from "react";
 import ChildComponent from "./childComponent";

 export default function Parent(){

 const handleParentFun = (value) =>{
   console.log("Call to Parent Component!",value);
 }
 return (<>
           This is Parent Component
           <ChildComponent 
             handleParentFun={(value)=>{
               console.log("your value -->",value);
               handleParentFun(value);
             }}
           />
        </>);
}

Дочірній компонент

import React from "react";


export default function ChildComponent(props){
  return(
         <> This is Child Component 
          <button onClick={props.handleParentFun("YoureValue")}>
            Call to Parent Component Function
          </button>
         </>
        );
}

1
Щоб додати значення своїй відповіді, спробуйте додати коротке пояснення того, що робить цей код.
— Cray

коли ви натискаєте кнопку в дочірньому компоненті, тоді функція Дзвінок до батьківського компонента через реквізит.
— Омкеш Саджанвар

1
Що робити, якщо функція має параметри? Як ви передаєте параметри батькові?
— alex351

так! @ alex351 ми можемо впоратися з таким сценарієм. В дочірніх компонентах -> onClick = {props.handleParentFun ("YoureValue")} У батьківському компоненті -> handleParentFun = {(значення) => {console.log (); handleChildFun (значення); }}
— Омкеш Саджанвар

0

Реагуйте 16+

Дочірній компонент

import React from 'react'

class ChildComponent extends React.Component
{
    constructor(props){
        super(props);       
    }

    render()
    {
        return <div>
            <button onClick={()=>this.props.greetChild('child')}>Call parent Component</button>
        </div>
    }
}

export default ChildComponent;

Батьківський компонент

import React from "react";
import ChildComponent from "./childComponent";

class MasterComponent extends React.Component
{
    constructor(props)
    {
        super(props);
        this.state={
            master:'master',
            message:''
        }
        this.greetHandler=this.greetHandler.bind(this);
    }

    greetHandler(childName){
        if(typeof(childName)=='object')
        {
            this.setState({            
                message:`this is ${this.state.master}`
            });
        }
        else
        {
            this.setState({            
                message:`this is ${childName}`
            });
        }

    }

    render()
    {
        return <div>
           <p> {this.state.message}</p>
            <button onClick={this.greetHandler}>Click Me</button>
            <ChildComponent greetChild={this.greetHandler}></ChildComponent>
        </div>
    }
}
export default  MasterComponent;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.