If we have the React component Foo
that instantiates the class Bar
and we need to pass the HTMLCollection
element with ID foo
into Bar
, how can it be done?
Bar.js
should ideally remained unchanged.
I tried the following:
Foo.js
import Bar from './Bar'; const Foo = () => { const elem = document.getElementById('foo'); const bar = new Bar(elem, {}); return ( <div id="foo"> </div> ); }; export default Foo;
Bar.js
export default class Bar { constructor(domElement, config = {}) { console.log(domElement); // null console.log(domElement.getElementsByClassName('bar')); // null } }
but domElement
is always null
, maybe because when we run document.getElementById
, the element div#foo
has not been rendered yet.
Also tried the using useRef
:
Foo.js
import { useRef } from 'react'; import Bar from './Bar'; const Foo = () => { const elemRef = useRef(null); const bar = new Bar(elemRef, {}); return ( <div id="foo" ref={elemRef}> </div> ); }; export default Foo;
Bar.js
export default class Bar { constructor(domElement, config = {}) { console.log(domElement); // {current: null} console.log(domElement.getElementsByClassName('bar')); // Uncaught TypeError: domElement.getElementsByClassName is not a function } }
but getting the error
Uncaught TypeError: domElement.getElementsByClassName is not a function
What is the correct way to do this?
Advertisement
Answer
You can use useLayoutEffect hook which fires synchronously after all DOM mutations
useLayoutEffect(() => { const elem = document.getElementById("foo"); const bar = new Bar(elem, {}); }, []);