React Hooks: компонент Dropdown с внешней загрузкой данных

Хочу реализовать компонент dropdown (на react hooks) в который контент выпадающего списка загружается через функцию-параметр dataSource, т.е. что-то типа такого:

function Dropdown({ dataSource }) {
  if(!Array.isArray(dataSource) {
    assert.func(dataSource)
  }
  const [dataItems, setDataItems] = useState(undefined)

  useEffect(function resetDataItemsByDataSource() {
    setDataItems(typeof dataSource === 'function' ? undefined : Array.from(dataSource))
  }, [dataSource])

  useEffect(function initDataItems() {
    if(dataItems != null || typeof dataSource !== 'function') {
      return
    }
    Promise.resolve()
      .then(() => dataSource())
      .then(items => {
        // how detect that dataSource is changed???
        if(isDataSourceChanged()) {
          return
        }
        setDataItems(Array.from(items))
      })
  }, [dataSource, dataItems])

  // . . .
}

Проблема заключается в том, как определить, что когда данные из dataSource загрузились, то мы работаем все еще с тем же dataSource(ds), с которым начинали загрузку данных? Т.е. возможна такая ситуация, что изначально был указан ds1, данные начали грузиться, потом клиент указал ds2, данные начали грузиться с него, загрузка с ds2 была завершена и успешно сохранена в dataItems, после этого закончилась загрузка с ds1 и мы НЕ должны перезаписать последние актуальные данные с ds2. Как в хуках реакта наиболее корректно обработать этот кейс? Возможно стоит каждое изменение dataSource сохранять в useRef, а в then'е обработки результата загрузки сравнивать значение из useRef со значением dataSource на момент начала загрузки? (что-то типа такого):

  const dsRef = useRef(null) // <====

  useEffect(function initDataItems() {
    dsRef.current = dataSource // <====
    if(dataItems != null || typeof dataSource !== 'function') {
      return
    }
    Promise.resolve()
      .then(() => dataSource())
      .then(items => {
        if(dsRef.current !== dataSource) {  // <====
          return
        }
        setDataItems(Array.from(items))
      })
  }, [dataSource, dataItems])

Или есть более корректный способ?

P.S. функция resetDataItemsByDataSource была выделена в отдельный useEffect для того чтобы при изменении dataSource был сброшен в undefined значение dataItems и отработало условие:

if(dataItems != null || typeof dataSource !== 'function') {
  return
}

P.S.S. В этом всем мне не нравится, что получается как-то запутано и сложно, что наводит на мысли, что реализовано либо не правильно либо не оптимально.


Ответы (0 шт):