2016-03-22 2 views
4

Мне нужно иметь 2 sibling компоненты, и 1 из них должен иметь ссылку на другого - это возможно?Реакт - прохождение ref to sibling

Я попытался это:

<button ref="btn">ok</button> 
<PopupComponent triggerButton={this.refs.btn} /> 

И даже этот

<button ref="btn">ok</button> 
<PopupComponent getTriggerButton={() => this.refs.btn} /> 

Но я undefined в обеих ситуациях. Есть идеи?

Примечание: родительский компонент не будет работать для меня, потому что мне нужно иметь несколько наборов тех, как

<button /> 
<PopupComponent /> 
<button /> 
<PopupComponent /> 
<button /> 
<PopupComponent /> 

НЕ нравится:

<div> 
    <button /> 
    <PopupComponent /> 
</div> 
<div> 
    <button /> 
    <PopupComponent /> 
</div> 
<div> 
    <button /> 
    <PopupComponent /> 
</div> 
+0

Могу ли я спросить, почему вторая альтернатива не является жизнеспособным решением в вашем случае? Потому что именно так я решил бы эту проблему. – Nico

+0

ну, я думаю, это в основном только причины css ...Я использую semantic-ui - PopupComponent на самом деле либо отображается: none; или положение: абсолютное; и у родителя на этих 2 действительно беспорядок все ... – Ziarno

+0

Итак, вы просто используете ref, чтобы показать/скрыть «PopupComponent»? –

ответ

6

думаю, этот вопрос лучше всего ответить самая docs:

If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.

Не уверен, что именно то, что вы пытаетесь сделать, бу t моя догадка является родительским компонентом, и передача реквизита - это то, что вы действительно хотите здесь.

+1

Мне нужны refs, потому что я использую semantic-ui, и мне нужно захватить 1 элемент с помощью jQuery и это еще один элемент (popup trigger и popup target) – Ziarno

+1

Mixing реагировать и jQuery - очень плохая идея, с высоким риском взлома реагировать. Чтобы реагировать на свою магию (очень быстрые и эффективные обновления DOM), она нуждается в полной монополии на части DOM, которыми она управляет. – wintvelt

2

Я полностью согласен с цитатой, которую предоставил Марк Маккелви. То, что вы пытаетесь достичь, рассматривается как анти-шаблон в React.

Я добавлю, что создание родительского компонента необязательно означает, что он должен быть прямым родителем, вы можете создать родительский компонент дальше по цепочке, в которой вы можете отобразить массив всех ваших дочерних компонентов вместе , имея логику для координации между всеми детьми (или парами детей в соответствии с вашим примером), сидите внутри вашего родителя.

Я создал грубый пример концепции, которая должна сделать трюк:

class A extends React.Component { 
    onClick(key) { 
     alert(this.refs[key].refs.main.innerText); 
    } 

    render() { 
     var children = []; 
     for (var i = 0; i < 5; i++) 
      children.push.apply(children, this.renderPair(i)); 

     return (
      <div> 
       {children} 
      </div> 
     ); 
    } 

    renderPair(key) { 
     return [ 
      <B ref={'B' + key} key={'B' + key} onClick={this.onClick.bind(this, 'C' + key)}/>, 
      <C ref={'C' + key} key={'C' + key} onClick={this.onClick.bind(this, 'B' + key)}/> 
     ]; 
    } 
} 

class B extends React.Component { 
    render() { 
     return <p ref="main" onClick={this.props.onClick}>B</p>; 
    } 
} 

class C extends React.Component { 
    render() { 
     return <p ref="main" onClick={this.props.onClick}>C</p>; 
    } 
} 


React.render(<A/>, document.getElementById('container')); 

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

+0

рендеринг массива действительно возможен? Я получаю сообщение об ошибке: 'Uncaught Error: Invariant Violation: EventPopup.render(): должен быть возвращен действительный ReactComponent. Возможно, вы вернули undefined, массив или какой-либо другой недопустимый объект. ' – Ziarno

+0

Какая версия вы используете? Сегодня я сделал то же самое. – iMoses

+0

Реакт версии 0.14.3 – Ziarno

0

special-props

Специальные Реквизит Предупреждение Большинство реквизита на элементе JSX передаются в компонент, однако, есть две специальные опоры (реф и ключ), которые используются React, и, таким образом, не передаются компонент.

Например, попытка доступа к this.props.key из компонента (например, функция рендеринга) не определена. Если вам нужно получить доступ к одному и тому же значению в дочернем компоненте, вы должны передать его в качестве другой опоры (например:). Хотя это может показаться излишним, важно отделить логику приложения от согласования намеков.

0

Следующий код помогает мне установить связь между двумя братьями и сестрами. Настройка выполняется в их родительском объекте во время вызовов render() и componentDidMount(). Надеюсь, поможет.

class App extends React.Component<IAppProps, IAppState> { 
    private _navigationPanel: NavigationPanel; 
    private _mapPanel: MapPanel; 

    constructor() { 
     super(); 
     this.state = {}; 
    } 

    // `componentDidMount()` is called by ReactJS after `render()` 
    componentDidMount() { 
     // Pass _mapPanel to _navigationPanel 
     // It will allow _navigationPanel to call _mapPanel directly 
     this._navigationPanel.setMapPanel(this._mapPanel); 
    } 

    render() { 
     return (
      <div id="appDiv" style={divStyle}> 
       // `ref=` helps to get reference to a child during rendering 
       <NavigationPanel ref={(child) => { this._navigationPanel = child; }} /> 
       <MapPanel ref={(child) => { this._mapPanel = child; }} /> 
      </div> 
     ); 
    } 
} 
Смежные вопросы