2016-06-21 5 views
106

У меня есть два компонента.Вызов дочернего метода от родителя

  1. Родитель компонент
  2. Детский компонент

Я пытался вызвать метод ребенка от Родителя, я попробовал этот путь, но не мог получить результат

class Parent extends Component { 
    render() { 
     return (
     <Child /> 
     <button onClick={Child.getAlert()}>Click</button> 
    ); 
    } 
    } 

    class Child extends Component { 
    getAlert() { 
     alert('clicked'); 
    } 
    render() { 
     return (
     <h1 ref="hello">Hello</h1> 
    ); 
    } 
    } 

Есть способ вызова метода child из родителя?

Примечание: родительская и компоненты находятся в двух разных файлах

ответ

138

Вы можете использовать refs.

class Parent extends Component { 
render() { 
    return (
    <div> 
     <Child ref="child" /> 
     <button onClick={() => this.refs.child.getAlert()}>Click</button> 
    </div> 
); 
} 
} 

class Child extends Component { 
getAlert() { 
    alert('clicked'); 
} 
render() { 
    return (
    <h1>Hello</h1> 
); 
} 
} 

Demonstration here


Редактировать

Струнные рефов, вероятно, будут устаревшими в будущем, так вот, как вы могли бы сделать это с callback refs:

const { Component } = React; 
 
const { render } = ReactDOM; 
 

 
class Parent extends Component { 
 
    render() { 
 
    return (
 
     <div> 
 
     <Child ref={instance => { this.child = instance; }} /> 
 
     <button onClick={() => { this.child.getAlert(); }}>Click</button> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class Child extends Component { 
 
    getAlert() { 
 
    alert('clicked'); 
 
    } 
 

 
    render() { 
 
    return (
 
     <h1>Hello</h1> 
 
    ); 
 
    } 
 
} 
 

 

 
render(
 
    <Parent />, 
 
    document.getElementById('app') 
 
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id="app"></div>

+9

Я устал, но в конечном итоге с этой ошибкой "_this2.refs.child.getAlert не является функцией « –

+0

», и я должен упомянуть, что эти компоненты находятся в двух отдельных файлах, и я импортирую его в родительский –

+0

. В этом случае я бы предложил изменить ваш вопрос, чтобы отразить, что они находятся в двух разных файлы и размещение точного кода, вызывающего проблемы. – rossipedia

19

https://facebook.github.io/react/tips/expose-component-functions.html для больше ответов реф здесь Call methods on React children components

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

В общем, данные должны передаваться по дереву через опоры. Есть несколько исключений из этого (например, вызов .фокуса() или запуск одноразовой анимации, которая на самом деле не «изменяет» состояние), но в любое время, когда вы подвергаете метод «set», реквизиты обычно лучший выбор. Постарайтесь сделать так, чтобы внутренний компонент ввода беспокоился о его размере и внешности, чтобы ни один из его предков не делал.

+0

Вот источник этого ответа: https://discuss.reactjs.org/t/is-it-bad-practice-to-call-child-component-methods-from-parent/1821/2. Нет проблем со ссылкой на других, но, по крайней мере, в некоторых ссылках. – Jodo

15

Вы можете использовать другой шаблон здесь:

class Parent extends Component { 
render() { 
    return (
    <div> 
     <Child setClick={click => this.clickChild = click}/> 
     <button onClick={() => this.clickChild()}>Click</button> 
    </div> 
); 
} 
} 

class Child extends Component { 
componentDidMount() { 
    this.props.setClick(this.getAlert) 
} 
getAlert() { 
    alert('clicked'); 
} 
render() { 
    return (
    <h1 ref="hello">Hello</h1> 
); 
} 
} 

Что она делает это, чтобы установить метод clickChild родителя, когда ребенок установлен. Таким образом, когда вы нажимаете кнопку в родительском, она вызывает callChild, которая вызывает getAlert для child.

Это также работает, если ваш ребенок обернут соединением(), поэтому вам не нужен взлом getWrappedInstance().

Обратите внимание, что вы не можете использовать onClick = {this.clickChild} в родительском объекте, потому что, когда родитель выведен, дочерний объект не установлен, поэтому this.clickChild еще не назначен. Использование onClick = {() => this.clickChild()} отлично, потому что, когда вы нажимаете кнопку this.clickChild, уже должны быть назначены.

+1

Я получаю '_this2.clickChild не функция' почему? – tatsu

+0

это не сработало для меня: https://github.com/kriasoft/react-starter-kit/issues/909#issuecomment-252969542 – tatsu

+0

Вы использовали onClick = {this.clickChild} или onClick = {() => this .clickChild()}? Первый из них не будет работать из-за причины в ответе «Примечание ...». Подход ref не будет работать, если вы упакуете свой компонент в connect() для сокращения. – brickingup

Смежные вопросы