Альтернатива пользовательскому вызову ловушки внутри useEffect - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть текущий компонент:

const Timeline = ({ threshold, throttle }) => {
  const [films, setFilms] = useState([])
  const [page, setPage] = useState(1)
  const [loadMoreLock, setLoadMoreLock] = useState(false)
  const [
    localStorageFilmsCache,
    setLocalStorageFilmsCache
  ] = useLocalStorage('filmsCache', films);

  useEffect(() => {
    const fetchFilms = async () => {
      try {
        const res = await fetch(
          `${API_PATH_BASE}/${API_VERSION}/${TRENDING_ENDPOINT}/movie/week?api_key=${THE_MOVIE_DB_API_KEY}&page=${page}`, {
            method: 'GET',
          }
        )
        const json = await res.json()

        if (page === 1) {
          setFilms((films) => json.results)
        } else {
          setFilms((films) => ([
            ...films,
            ...json.results,
          ]))
        }

        setLoadMoreLock(() => false)
      } catch (e) {
        setFilms(() => null)
      }
    }

    if (!loadMoreLock) {
      fetchFilms()
    }

    // Scroll handler fns...
  }, [page, loadMoreLock, threshold, throttle])

  // Return JSX..

И пользовательский хук:

const useLocalStorage = (key, initialValue = '') => {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const currValue = window.localStorage.getItem(key)

      return currValue ? JSON.parse(currValue) : initialValue
    } catch (e) {
      return initialValue
    }
  })

  const setValue = (value) => {
    try {
      const valueToStore = value instanceof Function
        ? value(storedValue)
        : value

      setStoredValue(() => valueToStore)

      window.localStorage.setItem(key, JSON.stringify(valueToStore))
    } catch (e) {}
  }

  return [
    storedValue,
    setValue,
  ]
}

Я хотел создать клиентский кеш для вызова API, используя мой пользовательский хук localStorage. В текущем контексте мне пришлось бы использовать свой пользовательский хук (и состояние, и установщик fn) внутри fn, который получает по умолчанию параметр useEffect, что невозможно. Я довольно плохо знаком с крючками, и мне трудно думать об альтернативах. Я мог бы сделать это без моего хука localStorage, но было бы неплохо повторно использовать логи c, которые я уже использовал. Спасибо!

1 Ответ

0 голосов
/ 05 февраля 2020

Вы можете повторно использовать свою функцию без хуков. Крючки важны, если вы хотите, чтобы ваши данные реагировали. Ваш образец не должен быть реактивным. Если вы хотите, чтобы данные были реактивными, текущая реализация недействительна, так как вам потребуется useContext.

В настоящее время ваш useLocalStorage получает или устанавливает значение localStorage. Ваш useState не имеет значения, поскольку вы можете напрямую вернуть значение и сохранить его в других useState s (фильмы, страницы и т. Д. c). Если вы пытаетесь уменьшить количество вызовов до localStorage, это все равно не имеет значения, поскольку оно будет многократно загружаться с localStorage для каждого компонента, который использует useLocalStorage. Вы можете проверить это, вставив оператор console.log внутри storedValue useState init-функции. React context вызовет его один раз и предоставит его всем компонентам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...