I want to be able to municate with my react ponent from outside of the ponent in normal HTML (needed due to embedding a ponent in another system).
I've been researching this and I have seen advice that you can add ponent to window
by adding a ref on the rendered element like so:
ReactDOM.render(
<Hello
ref={(element) => {
window.helloComponent = element;
}}
/>,
rootElement
);
But for me it doesn't work and generates this warning:
index.js:27 Warning: Function ponents cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
The ponent doesn't get added to window object so the reference does not work from the html button outside of react ponent.
I've been trying various ways with createRef() to add to window but can't figure it out. I am unable to relate the forwardRef() docs to my current situation.
Here is my code:
const rootElement = document.getElementById("root");
if (rootElement) {
ReactDOM.render(
<Hello
ref={(element) => {
window.helloComponent = element;
}}
/>,
rootElement
);
}
function Hello() {
function alertOne() {
alert("hi from 1");
}
return (
<div>
<h1>Hello, world! </h1> <UpdateButton />
</div>
);
}
function UpdateButton() {
function alertTwo() {
alert("hi from 2");
}
return <button onClick={alertTwo}> Click Me Inside React</button>;
}
<script src=".6.3/umd/react.production.min.js"></script>
<script src=".6.3/umd/react-dom.production.min.js"></script>
<button onclick="window.helloComponent.alertOne()">
Click me outside react
</button>
<div id="root"></div>
I want to be able to municate with my react ponent from outside of the ponent in normal HTML (needed due to embedding a ponent in another system).
I've been researching this and I have seen advice that you can add ponent to window
by adding a ref on the rendered element like so:
ReactDOM.render(
<Hello
ref={(element) => {
window.helloComponent = element;
}}
/>,
rootElement
);
But for me it doesn't work and generates this warning:
index.js:27 Warning: Function ponents cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
The ponent doesn't get added to window object so the reference does not work from the html button outside of react ponent.
I've been trying various ways with createRef() to add to window but can't figure it out. I am unable to relate the forwardRef() docs to my current situation.
Here is my code:
const rootElement = document.getElementById("root");
if (rootElement) {
ReactDOM.render(
<Hello
ref={(element) => {
window.helloComponent = element;
}}
/>,
rootElement
);
}
function Hello() {
function alertOne() {
alert("hi from 1");
}
return (
<div>
<h1>Hello, world! </h1> <UpdateButton />
</div>
);
}
function UpdateButton() {
function alertTwo() {
alert("hi from 2");
}
return <button onClick={alertTwo}> Click Me Inside React</button>;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<button onclick="window.helloComponent.alertOne()">
Click me outside react
</button>
<div id="root"></div>
I would like to know the right technique for accessing alertOne()
and alertTwo()
from outside of any react ponent, just from html on same page the ponent renders.
-
One issue is the typo in your button:
helloConponent
. – ray Commented Sep 2, 2020 at 3:12 - Thanks updated. Unfortunately not the main issue. – Guerrilla Commented Sep 2, 2020 at 3:16
3 Answers
Reset to default 6Saving the function in the window object:
const rootElement = document.getElementById("root");
if (rootElement) {
ReactDOM.render(
<Hello />,
rootElement
);
}
function Hello() {
function alertOne() {
alert("hi from 1");
}
window.helloComponentAlert = alertOne;
return (
<div>
<h1>Hello, world! </h1> <UpdateButton />
</div>
);
}
function UpdateButton() {
function alertTwo() {
alert("hi from 2");
}
return <button onClick={alertTwo}> Click Me Inside React</button>;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script>
const handleClick = () => {
window.helloComponentAlert();
}
</script>
<button onclick="handleClick()">Click me outside react</button>
<div id="root"></div>
Event driven approach:
const rootElement = document.getElementById("root");
if (rootElement) {
ReactDOM.render(
<Hello/>,
rootElement
);
}
function Hello() {
function alertOne() {
alert("hi from 1");
}
React.useEffect(() => {
window.addEventListener(
"someEvent",
alertOne,
false
);
}, []);
return (
<div>
<h1>Hello, world! </h1> <UpdateButton />
</div>
);
}
function UpdateButton() {
function alertTwo() {
alert("hi from 2");
}
return <button onClick={alertTwo}> Click Me Inside React</button>;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script>
const handleClick = () => {
var someEvent = new Event("someEvent");
window.dispatchEvent(someEvent);
}
</script>
<button onclick="handleClick()">Click me outside react</button>
<div id="root"></div>
Event driven approach with passing additional data:
const rootElement = document.getElementById("root");
if (rootElement) {
ReactDOM.render(
<Hello/>,
rootElement
);
}
function Hello() {
function alertOne(e) {
alert("hi from 1 " + e.detail);
}
React.useEffect(() => {
window.addEventListener(
"someEvent",
alertOne,
false
);
}, []);
return (
<div>
<h1>Hello, world! </h1> <UpdateButton />
</div>
);
}
function UpdateButton() {
function alertTwo() {
alert("hi from 2");
}
return <button onClick={alertTwo}> Click Me Inside React</button>;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<script>
const handleClick = () => {
var someEvent = new CustomEvent("someEvent", {detail: "SomeAdditionalData"});
window.dispatchEvent(someEvent);
}
</script>
<button onclick="handleClick()">Click me outside react</button>
<div id="root"></div>
const rootElement = document.getElementById("root");
window.alertEvent = new Event('alert');
if (rootElement) {
ReactDOM.render(
<Hello/>,
rootElement
);
}
function Hello() {
function alertOne() {
alert("hi from 1");
}
window.addEventListener('alert',alertOne);
return (
<div>
<h1>Hello, world! </h1> <UpdateButton />
</div>
);
}
function UpdateButton() {
function alertTwo() {
alert("hi from 2");
}
return <button onClick={alertTwo}> Click Me Inside React</button>;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<button onclick="window.dispatchEvent(window.alertEvent)">
Click me outside react
</button>
<div id="root"></div>
Here is an example that I have created where you could pass some values as well using the event publish subscribe pattern in javascript.
https://codesandbox.io/s/react-playground-forked-r7dfn?file=/index.js