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
Proper Use of Const for Defining Functions
(Deep) Copying an Array Using Jquery
Executing JavaScript from Python
Triggering a JavaScript Click() Event at Specific Coordinates
How to Break Nested Loops in JavaScript
Dynamically Arrange Some Elements Around a Circle
Getting the User Id from a Database Trigger in Cloud Functions for Firebase
Get Event Listeners Attached to Node Using Addeventlistener
Jqgrid - Maintain Check Box Selection State - Page Refresh/Redirect/Reload
How to Find a Number in a String Using JavaScript
Positive Look Behind in JavaScript Regular Expression
How to Stop a Window.Setinterval in JavaScript
JavaScript .Replace Command Replace Page Text
Using Chrome, How to Find to Which Events Are Bound to an Element