首页 > 解决方案 > React:使用带有 React 钩子的 localStorage,除非单击按钮,否则如何使我的组件不重新加载?

问题描述

目前,我的应用程序在安装主组件时使用 fetch 访问外部数据,每当我重新加载页面时,它都会重新加载数据并重置我链接到它的本地存储项目。

但是,我想要的是:1)第一次用户打开页面时,必须加载整个数据集 2)如果用户删除表中的任何项目,然后关闭选项卡或重新加载页面,那些删除的项目不应该重新出现在数据集和表格中(除非单击“重新加载”按钮)

我的主要组件目前看起来像这样:

function App() {
  const DEFAULT_ERROR = null
  const DEFAULT_IS_LOADED = false
  const DEFAULT_DATASET = []
  const DEFAULT_INPUT_VALUE = ''
  const DEFAULT_DROPDOWN_VALUE = 'year'
  const DEFAULT_GRAPH_DATA = []

  const URL = 'https://reqres.in/api/unknown'

 const [ error, setError ] = React.useState(DEFAULT_ERROR)
 const [ isLoaded, setIsLoaded ] = React.useState(DEFAULT_IS_LOADED)
 const [ dataset, setDataset ] = React.useState(DEFAULT_DATASET)

 const [ inputValue, setInputValue ] = React.useState(DEFAULT_INPUT_VALUE)
 const [ dropdownValue, setDropdownValue ] = React.useState(DEFAULT_DROPDOWN_VALUE)

 const { graphData, setGraphData } = React.useState(DEFAULT_GRAPH_DATA)

 localStorage.setItem('hasBeenLoaded', false)
 let hasBeenLoaded = JSON.parse(localStorage.getItem('hasBeenLoaded'))

 if (!hasBeenLoaded) {
  localStorage.setItem('hasBeenLoaded', true)
  hasBeenLoaded = JSON.parse(localStorage.getItem('hasBeenLoaded'))
  console.log(hasBeenLoaded)

  React.useEffect(() => {
    requestData(URL, setIsLoaded, setDataset, setError)
  }, [])
}

我尝试在本地存储中存储一个值,以跟踪应用程序是否已在用户 PC 上加载,因此它不会使用 fetch 请求重新运行 useEffect,但由于某种原因,它似乎仍在运行并且任何表我删除的项目在重新加载时重新出现。

requestData功能如下:

function requestData(url, setIsLoaded, setDataset, setError) {
  return fetch(url)
    .then(response => response.json())
    .then(
      (result) => { 
        setIsLoaded(true)

        for (let i=0; i < result.data.length; i++) {
          localStorage.setItem(result.data[i].id, JSON.stringify(result.data[i]))

          setDataset(
            prevDataset => [...prevDataset, JSON.parse(localStorage.getItem(result.data[i].id))]
          )
        }
      },
      (error) => {
        setIsLoaded(true)
        setError(error)
      }
    )
 }

我应该怎么做才能使我的组件按计划工作?这是我的,以防万一。

最好的问候,康斯坦丁

标签: javascriptreactjslocal-storagereact-hooks

解决方案


正如@charlietfl 所说,您始终将值设置hasBeenLoaded为false,因此它将始终获取数据,其工作逻辑是:

  1. 检查hasBeenLoaded变量是否存在于 LocalStorage
  2. 如果没有,请调用您的requestData方法(您甚至不需要useEffect
  3. 如果是,什么也不做

然后当用户单击重新加载按钮时,您将变量设置为 false

const hasBeenLoaded = localStorage.getItem('hasBeenLoaded')

if(!hasBeenLoaded){
  requestData(URL, setIsLoaded, setDataset, setError)
  localStorage.setItem('hasBeenLoaded', true)
}

推荐阅读