Video Tutorial Using a classic library in React


In this video I suggest you discover how to integrate a non react library in react.

ref & useEffect ()

In general, libraries need to be grafted onto an element in the DOM so you will need to create a reference to get the element. Then, we will initialize the library when the component is mounted.

import React, {useRef, useEffect} from 'react'
import flatpickr from 'flatpickr'

import 'flatpickr / dist / themes / confetti.css'

export function Datepicker ({value, onChange}) {
  const inputRef = useRef ()

  // We initialize flatpickr
  useEffect (() => {
    if (inputRef.current) {
      flatpickr (inputRef.current)
      return () => f.destroy ()
    }
  }, (inputRef.current))

  return 
}

You will also and above all have to think about returning a function that will allow you to detach the library when the component is dismantled (to avoid side effects).

Synchronize value

Now we must also think about adding the behavior that allows to synchronize the value, but also to report the changes. It will often be necessary to create a reference to store the instance of our library.

export function Datepicker ({value, onChange}) {
  const flatpickrRef = useRef ()

  // ...

  useEffect (() => {
    if (inputRef.current) {
      const f = flatpickr (inputRef.current, {
        onChange: handleChange
      })
      flatpickrRef.current = f
      return () => f.destroy ()
    }
  }, (inputRef.current))

  // When the value changes we update on flatpickr
  useEffect (() => {
    if (flatpickrRef.current) {
      flatpickrRef.current.setDate (value, false)
    }
  }, (value))

  // ...
}

Be careful however, the callback received as a parameter (here we change) may need to change. We must therefore foresee this case and update the instance.

export function Datepicker ({value, onChange}) {
  useEffect (() => {
    if (flatpickrRef.current) {
      flatpickrRef.set ('onChange', (_, date) => onChange (date))
    }
  }, (we change))
}

Another solution (if the library does not allow changing the callbacks after initialization) is to use a reference for the callback.

export function Datepicker ({value, onChange}) {
  // ...
  const onChangeRef = useRef (onChange)
  onChangeRef.current = onChange
  const handleChange = useCallback ((_, date) => {
    onChangeRef.current (date)
  }, ())

  // We initialize flatpickr
  useEffect (() => {
    if (inputRef.current) {
      const f = flatpickr (inputRef.current, {
        onChange: handleChange
      })
      flatpickrRef.current = f
      return () => f.destroy ()
    }
  }, (inputRef.current))

  // ...
}

And There you go !

to summarize

  • Initialize the library using the useEffect
  • Use the cleaning function to remove edge effects
  • Manage changes of props (callback for example but also changes of value)