2017-02-19 18 views
2

У меня есть пользовательский компонент Foo, чей «bar» функция, которую я хочу, чтобы вызвать извне:React - Срабатывание метод компонент из другого компонента, как принадлежащие в том же делают()

class Foo extends React.Component { 
    bar() { ... } 
} 

Я оказание Foo наряду с button, целью которого является запуск Foo.bar():

render() { 

return (
    <Foo ...> 
    </Foo> 
    <Button onClick={I want to trigger Foo.bar()} /> 
); 
} 

вещи, которые я пробовал:

  1. Перемещение <Button > внутри Foo, а затем добавить onClick из <Button/> в Foo's конструктору - связывание OnClick не работает - я вижу, что прилагается, но <Button /> еще не вызывает onClick. (или, если он может работать, как это сделать правильно)?

Решения, которые не делают то, что я хочу:

  1. Я вижу один potential solution, который предлагает слушать мыши во всем MyComponent, а затем сделать некоторые DOM-опрос, чтобы найти, если фактическая кнопка был нажат. Однако это не сработает для меня, потому что MyComponent делает не собственными этими кнопками (эти кнопки не являются MyComponent.props.children), и я предпочел бы мозговой штурм решения, которое не заставило бы меня переместить кнопки внутри.

  2. Another potential solution не работает: Я не могу иметь render() вернуть значение <MyComponent /> в var myComp, то внутри <Button onClick={() => {myComp.blah()}} />, потому что сам <Button /> инстанциируется внутри <MyComponent /> как ребенок! (и они оба находятся в том же вызове render() anyways)

  3. Часть b) # 2 (выше), используя метод статического класса React-Component, также не будет работать: мне нужно это для каждого экземпляра основа.

  4. Using app state (such as a store) не то, что я хочу, либо - MyComponent предназначается, чтобы быть повторно usaable виджет и не могут быть привязаны к определенному состоянию приложения или прослушивания каких-либо конкретных магазинов или магазинов действий.

Любые предложения?

Благодаря

ответ

3

Вы можете определить функцию на родителя, который имеет реф ребенку Foo. Эта функция вызовет this.refs.foo.yourFunction(); Затем вы передаете эту функцию в кнопку, поэтому, когда нажимается кнопка, вызывается функция родителя. Добавлен пример здесь, когда нажатие кнопки переключит состояние компонента Foo (но оно может сделать что угодно).

Пример ниже

class Parent extends React.Component { 
 
    triggerFoo() { 
 
    this.foo.toggle(); 
 
    } 
 
    render() { 
 
    return (
 
     <div> 
 
     <Foo ref={foo => this.foo = foo} /> 
 
     <Button onClick={this.triggerFoo.bind(this)}/> 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 
class Foo extends React.Component { 
 
    state = {foo: false} 
 
    toggle() { 
 
    this.setState({ 
 
     foo: !this.state.foo 
 
    }); 
 
    } 
 
    render() { 
 
    return (
 
     <div> 
 
     Foo Triggered: {this.state.foo.toString()} 
 
     </div> 
 
    ); 
 
    } 
 
} 
 

 

 
class Button extends React.Component { 
 
    render() { 
 
    return (
 
     <button onClick={this.props.onClick}> 
 
     Click This 
 
     </button> 
 
    ); 
 
    }; 
 
} 
 
ReactDOM.render(<Parent />, document.getElementById('root'));
<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="root" />

+0

Да, это будет работать великолепно.Большое спасибо за ясное объяснение и предложение :) – dev

+2

Быстрое примечание: похоже, что «строка» refs не поддерживается последней версией реакции? Согласно последним документам реагирования (февраль 2017), ref теперь принимает обратный вызов, который имеет этот элемент в качестве первого параметра. Таким образом, ваше выше было бы ref = {(foo) => {this.foo = foo}} (на самом деле я получал жесткое инвариантное нарушение, используя устаревшее ref api, но используя обратный шаблон исправил проблему) – dev

+1

Да, это хорошо идея. String refs все равно должен работать для общего случая, но в зависимости от того, как структурирован ваш код и «это», похоже, что это может привести к проблемам. Я обновил ответ, чтобы отразить использование обратного вызова для ссылки. – noveyak

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

  • Нет связанных вопросов^_^