如何将数组与 setState 一起使用?

IT技术 javascript arrays reactjs ecmascript-6 state
2021-05-26 23:17:56

我目前正在使用以下内容将我的数组映射到 setState 但没有设置任何内容并且没有记录任何错误。如果我一行一行地明确地写出来,它就可以工作。关于如何解决这个问题的任何想法或建议?

使用数组设置状态:(不设置状态)

const myData = ['message', 'photo', 'isLoggedInhoto'];
const newData = [];

{[...Array(myData.length)].map((x, index) =>
  newData.push(myData[index])
)}

this.setState({
  newData: localStorage.getItem(newData),
})

逐行(这有效并且设置状态):

this.setState({
  message: localStorage.getItem('message'),
  photo: localStorage.getItem('photo'),
  isLoggedIn: localStorage.getItem('isLoggedIn')
})
3个回答

不幸的是,Javascript 不会按照您的代码假定的方式解构数组。您不能将数组设置为对象的键并让它扩展到数组中的所有项目。您的代码只是设置名为 的键newData,而不是设置键数组。对象字面量中的 Javascript 键不必被引用。这是使用字符串“newData”,而不是变量。

对于localStorage.getItem(),第一个参数是字符串键名。不能通过使用数组作为键一次获得多个键。

这是一种干净的方法,使用 ES6 语法:

this.setState(
    [ 'message', 'photo', 'isLoggedInhoto' ].reduce( ( memo, key ) => ({
        ...memo,
        [ key ]: localStorage.getItem( key )
    }), {} )
);

解释:

我们正在减少一个数组,这听起来像它的作用。它将数组中的所有项目简化为一件事。第一个参数memo是“蓄能”,这意味着我们要减少和建设上,因为我们去的东西,第二项是当前元素('message''photo'等)。

具有这种语法的箭头函数() => ({})意味着返回一个对象。特别是包裹花括号的括号。如果没有括号包裹,如在 中() => {},则花括号内的任何内容都被解释为常规函数体。

此语法:

{ ...memo }

表示将旧对象的内容复制memo到新对象中。这是 es6 扩展运算符。

最后,要根据变量名称设置键,请将其包装在 中[],如

{ [ key ]: ... }

因此,如果键是'message',它将创建一个对象{ message: ... }

整个代码将产生一个对象,如

{
    message: localStorage.getItem('message'),
    photo: localStorage.getItem('photo'),
    isLoggedIn: localStorage.getItem('isLoggedIn')
}

然后传递给setState所有键以便正确设置。

此外,一般.map()不应以这种方式使用。.map()旨在用于返回一个新数组,其中旧值映射到一些新值。丢弃 return from.map()意味着您使用了错误的循环范例。

[].forEach()适用于不返回任何内容而是具有副作用的循环(例如推送到一些更高范围的数组)。但在这种情况下,两者都不理想,.reduce()基于数组生成对象在语义上更正确。

您正在尝试创建一个新的状态对象,该对象具有列表中的属性,以及localStorage使用列表作为键提取的数据

  1. 使用迭代列表 Array#map
  2. 在每次迭代中,使用列表中的键创建一个新对象,并从 中获取数据localStorageJSON.parse()如果您存储了字符串化的 JSON 数据,请不要忘记
  3. 散布在阵列并使用创建一个新对象Object#assign
  4. 将结果对象设置为您的状态。

代码:

const myData = ['message', 'photo', 'isLoggedInhoto'];
const state = Object.assign({}, ...myData.map((prop) => ({
  [prop]: localStorage.getItem(prop) // or JSON.parse(localStorage.getItem(prop)) if your storing a JSON
})));

this.setState(state);

您不能将数组用作对象的键和getItem.

您需要遍历newData并使用计算属性名称语法:

newData.forEach(key => this.setState({ [key]: localStorage.getItem(key) }))

或者在重构您的代码时,您可以通过一个循环和一个setState调用来实现它

const myData = ['message', 'photo', 'isLoggedInhoto']
const newData = {}

{[...Array(myData.length)].map((x, index) =>
  newData[myData[index]] = localStorage.getItem(myData[index])
)}

 this.setState(newData)