【问题标题】:React: using localStorage with React hooks, how would I make my components not reload unless the button is clicked?React:使用带有 React 钩子的 localStorage,除非单击按钮,否则如何使我的组件不重新加载?
【发布时间】:2020-06-14 20:31:07
【问题描述】:

目前,我的应用在安装主组件时通过 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)
      }
    )
 }

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

最好的问候, 康斯坦丁

【问题讨论】:

  • @LoicH 你从哪里得到不能持久化 localStorage 的想法?
  • 它实际上似乎在第一次加载时将 hasBeenLoaded 保存为“true”在本地存储中,但由于某种原因我仍然无法让它不重新加载数据
  • 您在存储中将 hasBeenLoaded 设置为 false,甚至还没有检查它。建议你再思考一下hasBeenLoaded 的逻辑
  • @LoicH localStorage 实际上是唯一可以可靠地保存在浏览器中的东西,哈哈
  • 我认为关闭窗口/重新打开它会清除本地存储

标签: javascript reactjs local-storage react-hooks


【解决方案1】:

正如@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)
}

【讨论】:

    猜你喜欢
    • 2020-03-24
    • 2021-06-25
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 2020-05-21
    • 2021-06-10
    • 2022-01-10
    相关资源
    最近更新 更多