Подтвердить что ты не робот

Есть ли способ доступа к экземпляру родительского компонента в React?

Я знаю, что это не функциональный подход, чтобы иметь возможность сделать что-то вроде this.parent в компоненте React, и я не могу найти никаких свойств на экземпляре компонента React, который приводит к родительскому элементу, но я просто глядя, чтобы иметь возможность делать некоторые вещи, когда мне это нужно.

Прежде, чем кто-нибудь потеряет время, объяснив это не функциональным "образом", понимаем, что мне это нужно из-за следующего, которого я пытаюсь достичь:

Постройте транспилятор для механизма Template для Meteor Spacebars, модель рендеринга которого принимает во внимание родительские компоненты/шаблоны.

Я уже создал транспилятор, который модифицирует выходной jsx для достижения этого. Я делаю это, передавая parent={this} во всех дочерних компонентах. Однако после того, как мне пришло в голову, возможно, я просто ничего не знаю о том, что даст мне способ доступа к экземпляру родительского компонента без дополнительных модификаций транспиляции.

Любые советы будут высоко оценены.

4b9b3361

Ответ 1

Обновление для React 0.13 и новее

Component._owner был устаревшим в React 0.13, а _currentElement больше не существует в качестве ключа в this._reactInternalInstance. Поэтому, используя нижеприведенное решение, бросаем Uncaught TypeError: Cannot read property '_owner' of undefined.

Альтернативой является, начиная с React 16, this._reactInternalFiber._debugOwner.stateNode.


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

В публичном API ничего нет, что позволит вам получить то, что вы хотите. Вы можете получить это, используя внутренности React, но поскольку это частный API, который может сломаться при в любое время.

Повторяю: вы почти наверняка не будете использовать это в каком-либо производственном коде.

Тем не менее, вы можете получить внутренний экземпляр текущего компонента с помощью this. _reactInternalInstance. Там вы можете получить доступ к элементу через свойство _currentElement, а затем экземпляр владельца через _owner._instance.

Вот пример:

var Parent = React.createClass({
  render() {
      return <Child v="test" />;
  },

  doAThing() {
    console.log("I'm the parent, doing a thing.", this.props.testing);
  }
});

var Child = React.createClass({
  render() {
    return <button onClick={this.onClick}>{this.props.v}</button>
  },

  onClick() {
    var parent = this._reactInternalInstance._currentElement._owner._instance;
    console.log("parent:", parent);
    parent.doAThing();
  }
});

ReactDOM.render(<Parent testing={true} />, container);

И здесь рабочий пример JSFiddle: http://jsfiddle.net/BinaryMuse/j8uaq85e/

Ответ 2

Нет ничего плохого, если вам нужно получить доступ к родительским реквизитам и функциям от детей.

Дело в том, что вы никогда не должны использовать внутренности React и недокументированные API.

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

Передача реквизита для детей

class Parent extends React.Component {

    constructor(props) {
        super(props)

        this.fn = this.fn.bind(this)
    }

    fn() {
        console.log('parent')
    }

    render() {
        return <Child fn={this.fn} />
    }

}

const Child = ({ fn }) => <button onClick={fn}>Click me!</button>

Рабочий пример

Использование контекста (если нет прямого отношения родителя/дочернего элемента)

class Parent extends React.Component {

    constructor(props) {
        super(props)

        this.fn = this.fn.bind(this)
    }

    getChildContext() {
        return {
            fn: this.fn,
        }
    }

    fn() {
        console.log('parent')
    }

    render() {
        return <Child fn={this.fn} />
    }

}

Parent.childContextTypes = {
    fn: React.PropTypes.func,
}

const Child = (props, { fn }) => <button onClick={fn}>Click me!</button>

Child.contextTypes = {
    fn: React.PropTypes.func,
}

Рабочий пример