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?
CodePudding user response:
You can use useLayoutEffect hook which fires synchronously after all DOM mutations
useLayoutEffect(() => {
const elem = document.getElementById("foo");
const bar = new Bar(elem, {});
}, []);