Reputation: 149
If I have a third party library that I would normally initialize like so:
class App {
constructor(props) {
this.helperLibrary = new HelperLibrary();
this.state = { data: null };
}
}
How would I go about initializing it in a functional component using react hooks?
So updated code would look something like:
const App = () => {
const [data, setData] = useState(null);
// Would I write something like this here??
helperLibrary = new HelperLibrary();
// Or would I use something like useEffect since
// constructor runs when the component is created?
useEffect = (() => {
helperLibrary = new HelperLibrary();
}, []);
};
Upvotes: 9
Views: 5515
Reputation: 31
Another example using the Plyr as the third party library while using react hooks.
const MediaPlayer = () => {
const playerRef = useRef(null);
useEffect(() => {
const playerId = `react-plyr-${randomUid()}`;
playerRef.current.id = playerId;
const player = new Plyr(`#${playerId}`);
return () => {
if (player != null) {
player.destroy();
}
};
}, [])
return (<audio ref={playerRef} controls></audio>);};
Upvotes: 0
Reputation: 31
If you need to destroy the instance after component unmounts
const App = () => {
const [helperLibrary, setHelperLibrary] = useState(null);
const [data, setData] = useState(null);
useEffect(() => {
const helperLibaryInstance = new HelperLibrary();
setHelperLibrary(helperLibaryInstance);
return () => {
helperLibaryInstance.destroy()
}
}, [])
...
return helperLibrary && (
<Component />
)
};
else this
const App = () => {
const [data, setData] = useState(null);
const helperLibrary = useMemo(() => {
const helperLibaryInstance = new HelperLibrary();
return helperLibaryInstance;
}, [])
...
return (
<Component />
)
};
Upvotes: 0
Reputation: 65
In our case we needed to bind the 3rd party library to a DOM element and pass props to init. I ended up using useRef and useEffect together:
const App = (props) => {
const container = useRef()
const helperLibrary = useRef(null)
const [data, setData] = useState(null);
useEffect = (() => {
if (!helperLibrary.current) { // runs only once
helperLibrary.current = new HelperLibrary({
props,
// this needs to be last so it doesn't get owerwritten
container: container.current
})
} else { // if there is a way to update
helperLibrary.current.update({
props
})
}
}, [props]);
return (
<div ref={container} />
);
}
Upvotes: 2
Reputation: 15
// This will init when this file is imported.
// If you will use the library in multiple components,
// they will reinit each time you use this syntax.
helperLibrary = new HelperLibrary();
const App = () => {
const [data, setData] = useState(null);
// This will reinit on every render
helperLibrary = new HelperLibrary();
useEffect = (() => {
// This will also reinit on every render
helperLibrary = new HelperLibrary();
}, []);
}
In order to have single instance of this HelperLibrary() you can init it on a different file, by
// You can call this from many files, and only one instance of this class will be used.
export helperLibrary = new HelperLibrary();
then you can just import it on the other file
import {helperLibrary} from './HelperLibrary';
const App = () => {
const [data, setData] = useState(null);
useEffect = (() => {
helperLibrary.doSomething();
}, []);
I made a small workshop for this, you can see here: https://codesandbox.io/s/react-hooks-counter-demo-ppkjq
Upvotes: 1
Reputation: 22330
A simple way would be to initialize outside of a component:
const helperLibrary = new HelperLibrary();
const App = () => {
const [data, setData] = useState(null);
};
App
is going to be rendered first time (and not e.g. in different routes), the closest equivalent of constructor would be something like:
const App = () => {
const helperLibrary = useRef(null);
const [data, setData] = useState(null);
// note: useEffect would run AFTER first render, equivalent of componentDidMount,
// for equivalent of consturctor, we need sync code, e.g.:
if (!helperLibrary.current) {
helperLibrary.current = new HelperLibrary();
}
};
Upvotes: 8
Reputation: 1145
I think using this make sense as the function will be called only once,when the component is mounted, so initialization of the library should be done in this block.
useEffect(() => {
console.log('mounted the component');
helperLibrary = new HelperLibrary();
}, [])
Upvotes: 1
Reputation: 1
For stateless component in hooks use the syntax as function. It’s a recommendation of React.
I recommend to save in reference the new third library. Remember if use hook useRef you need to save in object current inside this hook. Something like this
function App() {
const [data, setData] = useState(null);
const helperLibrary = useRef();
helperLibrary.current = new HelperLibrary();
...
}
Upvotes: -1