Skip to content

Instantly share code, notes, and snippets.

@primaryobjects
Last active July 10, 2023 16:24
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save primaryobjects/64734b8fe3f54aa637f444c95f061eed to your computer and use it in GitHub Desktop.
Save primaryobjects/64734b8fe3f54aa637f444c95f061eed to your computer and use it in GitHub Desktop.
Calling a React component's methods from outside of React. Demo https://plnkr.co/edit/E6lPrL331KGxoikGinFm?p=preview
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery@3.1.1" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script data-require="tether@*" data-semver="1.4.0" src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<link data-require="bootstrap@4.0.5" data-semver="4.0.5" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />
<script data-require="bootstrap@4.0.5" data-semver="4.0.5" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/js/bootstrap.min.js"></script>
<script data-require="react@*" data-semver="15.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.0/react.min.js"></script>
<script data-require="react@*" data-semver="15.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.0/react-dom.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class='container'>
<h1>Hello World!</h1>
<button id='btnShow' type="button" class="btn btn-primary">Show</button>
<button id='btnHide' type="button" class="btn btn-primary">Hide</button>
<div id="translator" class='mt-5'></div>
<div id="output"></div>
</div>
<script src="translator.js"></script>
<script src="script.js"></script>
</body>
</html>
var translator = ReactDOM.render(React.createElement(Translator), document.getElementById('translator'));
$(function() {
$('#btnShow').click(function() {
$('#output').text('');
translator.show('Hola Mundo! Este es el control de Translator.', 'en', 'es', function(text) {
$('#output').text(text);
});
});
$('#btnHide').click(function() {
translator.hide();
});
});
class Translator extends React.Component {
constructor(props) {
super(props);
this.state = {
sourceLang: 'es',
destLang: 'en',
text: '',
isVisible: false
};
this.onTranslate = this.onTranslate.bind(this);
};
show(text, sourceLang, destLang, callback) {
this.setState({ isVisible: true, text: text, sourceLang: sourceLang, destLang: destLang, callback: callback });
}
hide() {
this.setState({ isVisible: false });
}
onTranslate() {
this.state.callback('Hello world! This is the Translator control.');
this.hide();
}
render() {
return (
<div className={ 'translator-component ' + (this.state.isVisible ? '' : 'hidden-xs-up') } >
<div className="card">
<div className="card-header">
Translator
</div>
<div className="card-block">
<h4 className="card-title"></h4>
<p className="card-text">
{ this.state.text }
</p>
<a href="#" className="btn btn-primary" onClick={ this.onTranslate }>Translate</a>
</div>
</div>
</div>
);
}
};
@baffleinc
Copy link

This is awesome. Thank you!

@tonthanhhung
Copy link

hi @yzorg, @baffleinc could you help to explain how to use the ref={(component) => window.translator = component; } instead of var translator = ReactDOM.render(...); ? where should ref be placed ?

@bramchi
Copy link

bramchi commented Jul 6, 2018

@tonthanhhung I was wondering the same thing. Here is a clarification for that new ref approach: https://brettdewoody.com/accessing-component-methods-and-state-from-outside-react/

@littlefroginnovations
Copy link

Does this not work on the new version of react? I can not get this example working at all. Just returns "Cannot read property 'show' of undefined". Tried using the ref method as well as old method.

@fannyhaz
Copy link

Thank you very much, it works! 👍

@alimovz
Copy link

alimovz commented Aug 21, 2019

@tonthanhhung I was wondering the same thing. Here is a clarification for that new ref approach: https://brettdewoody.com/accessing-component-methods-and-state-from-outside-react/

This is the proper way to do it.

@neeleshbisht99
Copy link

neeleshbisht99 commented Jun 25, 2020

@tonthanhhung I was wondering the same thing. Here is a clarification for that new ref approach: https://brettdewoody.com/accessing-component-methods-and-state-from-outside-react/

The above link is not working now !!
Is it related to this : https://stackoverflow.com/a/37950970/9131807

@neeleshbisht99
Copy link

neeleshbisht99 commented Jun 26, 2020

I guess this method ref={(component) => window.translator = component; } is for legacy versions(<= react@16.3).
For newer versions of react, we can make use of react hooks, forwardRef & useImperativeHandle hook.
For more info check this answer on stackoverflow : https://stackoverflow.com/a/37950970/9131807

@Partha177
Copy link

@tonthanhhung I was wondering the same thing. Here is a clarification for that new ref approach: https://brettdewoody.com/accessing-component-methods-and-state-from-outside-react/

Hi,
ReactDOM.render(<Page ref={(ourComponent) => {window.ourComponent = ourComponent}} />, document.getElementById("app"));
What is 'Page' here??
How to import it??

@amitshahc
Copy link

I had implemented this method when creating components using Class. now I am making it a functional component. Can anyone update how it will work with the functional component using react hooks?

Class-based components were easy to manage I think. Why react developer making it confusing and complicated using hooks?

@amitshahc
Copy link

I guess this method ref={(component) => window.translator = component; } is for legacy versions(<= react@16.3).
For newer versions of react, we can make use of react hooks, forwardRef & useImperativeHandle hook.
For more info check this answer on stackoverflow : https://stackoverflow.com/a/37950970/9131807

your link is no longer exists.. better describe your code here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment