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
JavaScript
x
14
14
1
import Bar from './Bar';
2
3
const Foo = () => {
4
const elem = document.getElementById('foo');
5
const bar = new Bar(elem, {});
6
7
return (
8
<div id="foo">
9
</div>
10
);
11
};
12
13
export default Foo;
14
Bar.js
JavaScript
1
7
1
export default class Bar {
2
constructor(domElement, config = {}) {
3
console.log(domElement); // null
4
console.log(domElement.getElementsByClassName('bar')); // null
5
}
6
}
7
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
JavaScript
1
15
15
1
import { useRef } from 'react';
2
import Bar from './Bar';
3
4
const Foo = () => {
5
const elemRef = useRef(null);
6
const bar = new Bar(elemRef, {});
7
8
return (
9
<div id="foo" ref={elemRef}>
10
</div>
11
);
12
};
13
14
export default Foo;
15
Bar.js
JavaScript
1
7
1
export default class Bar {
2
constructor(domElement, config = {}) {
3
console.log(domElement); // {current: null}
4
console.log(domElement.getElementsByClassName('bar')); // Uncaught TypeError: domElement.getElementsByClassName is not a function
5
}
6
}
7
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
JavaScript
1
5
1
useLayoutEffect(() => {
2
const elem = document.getElementById("foo");
3
const bar = new Bar(elem, {});
4
}, []);
5