Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there any way to access the parent component instance in React?

Tags:

reactjs

People also ask

How do you get parent value from React component?

In the parent component, create a callback function. This callback function will retrieve the data from the child component. Pass the callback function to the child as a props from the parent component. The child component calls the parent callback function using props and passes the data to the parent component.

Can parent component access child state React?

In React we can access the child's state using Refs. we will assign a Refs for the child component in the parent component. then using Refs we can access the child's state. Creating Refs Refs are created using React.

How do you pass a parent event in React?

To pass data from child to parent component in React:Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .


There's nothing wrong if you need to access the parent's props and functions from the children.

The point is that you should never use React internals and undocumented APIs.

First of all, they are likely to change (breaking your code) and, most importantly, there are many other approaches which are cleaner.

Passing props to children

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>

Working example

Using context (if there's no direct parent/child relation)

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,
}

Working example


Update for React 0.13 and newer

Component._owner was deprecated in React 0.13, and _currentElement no longer exists as a key in this._reactInternalInstance. Therefore, using the solution below throws Uncaught TypeError: Cannot read property '_owner' of undefined.

The alternative is, as of React 16, this._reactInternalFiber._debugOwner.stateNode.


You've already recognized that this is not a good thing to do almost always, but I'm repeating it here for people that don't read the question very well: this is generally an improper way to get things done in React.

There's nothing in the public API that will allow you to get what you want. You may be able to get to this using the React internals, but because it's a private API it's liable to break at any time.

I repeat: you should almost certainly not use this in any sort of production code.

That said, you can get the internal instance of the current component using this. _reactInternalInstance. In there, you can get access to the element via the _currentElement property, and then the owner instance via _owner._instance.

Here's an example:

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

And here's a working JSFiddle example: http://jsfiddle.net/BinaryMuse/j8uaq85e/


Tested with React 16

I was playing around with something similar using context, tho to anyone reading this, for most usual cases, accessing the parent is not advised!

I created a holder that when used, would always have a reference to the first holder up the display list, so its 'parent' if you will. Looked something like this:

const ParentContext = React.createContext(null);

// function to apply to your react component class
export default function createParentTracker(componentClass){

    class Holder extends React.PureComponent {

        refToInstance

        render(){
            return(
                <ParentContext.Consumer>
                {parent => {
                    console.log('I am:', this, ' my parent is:',parent ? parent.name : 'null');
                    return(
                        <ParentContext.Provider value={this}>
                            <componentClass ref={inst=>refToInstance=inst} parent={parent} {...this.props} />
                        </ParentContext.Provider>
                    )}
                }
                </ ParentContext.Consumer>
            )
        }
    }

    // return wrapped component to be exported in place of yours
    return Holder;
}

Then to use it you would pass your react component to the method when you export it like so:

class MyComponent extends React.Component {

    _doSomethingWithParent(){
        console.log(this.props.parent);  // holder
        console.log(this.props.parent.refToInstance);  // component
    }
}

// export wrapped component instead of your own
export default createParentTracker(MyComponent);

This way any component exporting the function will get its parent's holder passed in as a prop (or null if nothing is further up the hierarchy). From there you can grab the refToInstance. It will be undefined until everything is mounted though.