dannyyy
dannyyy

Reputation: 149

How do I initialize third party libraries while using react hooks?

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

Answers (7)

Prince Owusu
Prince Owusu

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

Mauro Salgado
Mauro Salgado

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

tonilaukka
tonilaukka

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

Ibrahim kuş
Ibrahim kuş

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

Aprillion
Aprillion

Reputation: 22330

A simple way would be to initialize outside of a component:

const helperLibrary = new HelperLibrary();

const App = () => {
  const [data, setData] = useState(null);
};


If you need to initialize it conditionally, just before 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

ravi
ravi

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

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

Related Questions