How to Access Component Methods from "Outside" in Reactjs

Call a React component method from outside

There are two ways to access an inner function. One, instance-level, like you want, another, static level.

Instance

You need to call the function on the return from React.render. See below.

Static

Take a look at ReactJS Statics. Note, however, that a static function cannot access instance-level data, so this would be undefined.

var onButtonClick = function () {
//call alertMessage method from the reference of a React Element!
HelloRendered.alertMessage();
//call static alertMessage method from the reference of a React Class!
Hello.alertMessage();
console.log("clicked!");
}

var Hello = React.createClass({
displayName: 'Hello',
statics: {
alertMessage: function () {
alert('static message');
}
},
alertMessage: function () {
alert(this.props.name);
},

render: function () {
return React.createElement("div", null, "Hello ", this.props.name);
}
});

var HelloElement = React.createElement(Hello, {
name: "World"
});

var HelloRendered = React.render(HelloElement, document.getElementById('container'));

Then do HelloRendered.alertMessage().

How to access component methods from “outside” in ReactJS?

React provides an interface for what you are trying to do via the ref attribute. Assign a component a ref, and its current attribute will be your custom component:

class Parent extends React.Class {
constructor(props) {
this._child = React.createRef();
}

componentDidMount() {
console.log(this._child.current.someMethod()); // Prints 'bar'
}

render() {
return (
<div>
<Child ref={this._child} />
</div>
);
}
}

Note: This will only work if the child component is declared as a class, as per documentation found here: https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a-ref-to-a-class-component

Update 2019-04-01: Changed example to use a class and createRef per latest React docs.

Update 2016-09-19: Changed example to use ref callback per guidance from the ref String attribute docs.

A way to call React component's method from outside (with it's state and props)

I would suggest for the case you described (different components on different levels need access to some state and manipulate it) to use React context. You can take a look also on state managers like Redux or MobX, but in this particular case it will be overhead since your application is not so "huge". Basically you need to create some separate folder (you can call it context), inside it you should create context itself, export it and wrap in it you most up level component so that all the children will be able to use it.

You can find an example here: https://codesandbox.io/s/spring-glitter-0vzul.

Here is a link to documentation: https://reactjs.org/docs/context.html

I can provide you some more details if you need

Access a React component method / state from outside the component

The Old Recommendation

Assigning the returned value from ReactDOM.render does allow access to the component and it's methods. For example, in a simple app, we might have:

const PageComponent = ReactDOM.render(<Page />, document.getElementById("app"));

which we can then access using PageComponent, and any of its methods can be accessed with PageComponent.METHOD.

However, according to the docs this might be changed or deprecated and is not recommended.

The New Recommendation

The new recommendation is to attach a callback ref to the root element. Using the same example above:

const PageComponent = ReactDOM.render(<Page ref={(pageComponent) => {window.pageComponent = pageComponent}}/>, document.getElementById("app"));

which we can then access using window.pageComponent, and any of its methods can be accessed with window.pageComponent.METHOD.

This also works for child components.

Here's a full example:

class ChildComponent extends React.Component {  constructor(props) {    super(props);    this.state = {      counter: 0    }  }
returnCounter = () => { return this.state.counter; } increment = (event) => { event.stopPropagation(); this.setState(prevState => { return { counter: prevState.counter + 1 } }) } render() { return ( <div onClick={this.increment}> Child Value - {this.state.counter} - Click to increment </div> ) }}
class Page extends React.Component { constructor(props) { super(props); this.state = { counter: 0 } }
returnCounter = () => { return this.state.counter; } increment = () => { this.setState(prevState => { return { counter: prevState.counter + 1 } }) }
render() { return ( <div onClick={this.increment}> <div>Parent Value - {this.state.counter} - Click to increment</div> <ChildComponent ref={(childComponent) => {window.childComponent = childComponent}}/> </div> ) }}
ReactDOM.render(<Page ref={(pageComponent) => {window.pageComponent = pageComponent}} />, document.getElementById("app"));
const parentBtn = document.getElementById("parentButton");parentBtn.addEventListener("click", event => { alert(window.pageComponent.returnCounter());});
const childBtn = document.getElementById("childButton");childBtn.addEventListener("click", event => { alert(window.childComponent.returnCounter());});
<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>
<button id="parentButton">Get Parent State</button><button id="childButton">Get Child State</button>

How to access state / functions outside of react component

Solution I found was to use a ref callback to make the DOM element a global variable.

<MyComponent ref={(MyComponent) => window.MyComponent = MyComponent})/>

Then you can access MyComponent with window.MyComponent, functions with window.MyComponent.method() or state variables with window.MyComponent.state.MyVar

My App.js:


function App() {
return (
<div className="App">
<PathfindingVisualizer ref={(PathfindingVisualizer) => {window.PathfindingVisualizer = PathfindingVisualizer}} />

</div>
);
}

Other.js:

handleMouseDown() {
window.PathfindingVisualizer.setState({mouseLeftDown: true});
}


Related Topics



Leave a reply



Submit