【问题标题】:Alternative to custom hook call inside useEffect替代 useEffect 中的自定义挂钩调用
【发布时间】:2020-05-19 17:50:15
【问题描述】:

我有当前组件:

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,
  ]
}

我想使用我的 localStorage 自定义挂钩为 API 调用构建客户端缓存。在当前上下文中,我必须在默认 fn useEffect 接收的参数中使用我的自定义钩子(状态和设置器 fn),这是不可能的。我对钩子很陌生,我很难考虑替代方案。我可以在没有 localStorage 钩子的情况下做到这一点,但是重用我已经掌握的逻辑会很好。 谢谢!

【问题讨论】:

  • 你可以在没有钩子的情况下重用你的函数。如果您希望数据具有反应性,那么挂钩很重要。您的样本不需要是反应性的。如果您确实希望数据具有响应性,则当前实现无效,因为您需要 useContext
  • 你指的是什么函数?使用本地存储?它处理当前状态的状态,您是否建议不要在其上使用 useState 而只是从 localStorage 获取值?供应商/消费者将如何解决这个问题?
  • 是的,useLocalStorage。目前您的useLocalStorage 获取或设置值到本地存储。您的 useState 无关紧要,因为您可以直接返回该值并将其存储在您的其他 useStates(电影、页面等)中。如果您试图减少对 localStorage 的调用,这仍然无关紧要,因为对于使用 useLocalStorage 的每个组件,它将从 localStorage 重复加载。您可以通过在storedValueuseState 初始化函数中插入一个console.log 语句来测试它。 React 上下文将调用它一次并将其提供给所有组件。
  • 我现在看到了,很有意义。我只是使用useLocalStorage 而不是useState 来保持状态。我并没有试图减少呼叫或任何事情,我只是没有意识到我可以将自定义挂钩用作useState。非常感谢!

标签: reactjs local-storage react-hooks use-effect react-state


【解决方案1】:

你可以在没有钩子的情况下重用你的函数。如果您希望数据具有反应性,那么挂钩很重要。您的样本不需要是反应性的。如果您确实希望数据具有响应性,则当前实现无效,因为您需要 useContext

当前您的useLocalStorage 获取或设置值到localStorage。您的 useState 无关紧要,因为您可以直接返回该值并将其存储在您的其他 useStates(电影、页面等)中。如果您试图减少对localStorage 的调用,这仍然无关紧要,因为对于使用useLocalStorage 的每个组件,它将从localStorage 重复加载。您可以通过在storedValueuseState 初始化函数中插入一个console.log 语句来测试它。 React context 将调用它一次并将其提供给所有组件。

【讨论】:

    猜你喜欢
    • 2021-11-22
    • 1970-01-01
    • 2020-05-17
    • 2020-07-14
    • 2021-12-07
    • 2021-09-10
    • 2023-02-06
    • 2020-02-15
    • 2020-08-01
    相关资源
    最近更新 更多