简体   繁体   English

如何比较对象并向/从 localStorage 添加/删除道具?

[英]How to compare objects and add/remove props to/from localStorage?

Ie I have an initial state:即我有一个初始状态:

const initialState = {
  val1: 1,
  val1: 2,
}

I want to check if my localStorage has all the same properties as my initialState which changes from time to time.我想检查我的localStorage是否具有与不时更改的initialState相同的所有属性。

  • If yes => skip to the next prop如果是 => 跳到下一个道具
  • if no => add prop: val to localStorage如果没有 => 将prop: val添加到localStorage
  • if there is a prop in localStorage that doesn't exist on initialState => remove the prop from localStorage .如果localStorage中有一个在initialState上不存在的道具 => 从localStorage删除道具。

Here I'm adding new props to localStorage which works but on every new prop I'm adding the entire newState.在这里,我向 localStorage 添加了新道具,它可以工作,但在每个新prop我都添加了整个 newState。

const setNewLocalStorage = () => {
  const localStorageState = getLocalStorageState()
  let newState = localStorageState
  Object.keys(initialState).map(key => {
    if (!localStorageState.hasOwnProperty(key)) {
      newState[key] = initialState[key]
      setStateToLocalStorage(newState)
    }
    return
  })
}

Answering the Y of XY回答 XY 的 Y

This is how you could store the data:这是您存储数据的方式:

const setNewLocalStorage = () => {
  Object.keys(initialState).map(key => {
    // Do various checking to decide whether or not to write
    if (!localStorageState.hasOwnProperty(key) || JSON.parse(localStorage.getItem(key)) !== initialState[key]) {
      localStorage.setItem(key, JSON.stringify(initialState[key])
    }

    // But actually that is more complex than need be.
    // Why not just store the data every time, and be done with?
    localStorage.setItem(key, JSON.stringify(initialState[key])
  })
}

Note that it is advisable to use JSON.stringify() and JSON.parse() when reading or writing to localStorage, because localStorage only stores strings, whilst your data appears to contain numbers.请注意,建议在读取或写入 localStorage 时使用JSON.stringify()JSON.parse() ,因为 localStorage 仅存储字符串,而您的数据似乎包含数字。


Second part:第二部分:

If there is a prop in localStorage that doesn't exist on initialState => remove the prop from localStorage如果 localStorage 中有一个在 initialState 上不存在的道具 => 从 localStorage 中删除该道具

I'm not sure this is advisable.我不确定这是可取的。 What if you add a plugin to your app which also stores data in localStorage?如果您向应用程序添加一个插件,该插件也将数据存储在 localStorage 中呢? You will end up clearing that plugin's data!您最终将清除该插件的数据!

So it might be safer instead to have a specific list of "oldKeys" which you want to remove.因此,拥有要删除的特定“oldKeys”列表可能更安全。 Or alternatively, namespace your keys, so you know which keys belong to this part of the app.或者,命名您的密钥,以便您知道哪些密钥属于应用程序的这一部分。

That said, here is how you could do what you asked for:也就是说,这里是你如何做你所要求的:

for (var i = localStorage.length; i--;) {
  var key = localStorage.key(i);
  if (!initialState.hasOwnProperty(key)) {
    localStorage.removeItem(key);
  }
}

I recommend looping backwards because the length and indexes may change if you remove items.我建议向后循环,因为如果删除项目,长度和索引可能会改变。 (Alternatively, extract the keys first and then forEach them.) (或者,先提取密钥,然后再提取它们。)

Simpler solution更简单的解决方案

I would encourage you to store the entire state object under one key:我鼓励您将整个状态对象存储在一个键下:

// Load state (but on first load, start with the defaultState)
var appState = JSON.parse(localStorage.getItem('appState') || "null") || defaultState;

// Save state
localStorage.setItem('appState', JSON.stringify(appState));

This is much simpler, fulfils both of your criteria, and keeps your appState separate from any other keys in localStorage.这更简单,满足您的两个标准,并使您的 appState 与 localStorage 中的任何其他键分开。

Note that on the first run localStorage.appState will be undefined, a value which JSON.parse() cannot handle, so we use ||请注意,在第一次运行时localStorage.appState将是未定义的,这是JSON.parse()无法处理的值,因此我们使用|| to convert that into "null" .将其转换为"null" Outside the parse, we use ||在解析之外,我们使用|| again to convert that null into the defaultState that new users should start with.再次将该null转换为新用户应该开始使用的 defaultState。

Also note that I renamed initialState to appState because that is a better name for something which can change.另请注意,我将initialState重命名为appState因为这是可以更改的更好名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM