如何使用setState数组?

时间:2016-12-13 21:47:52

标签: javascript arrays reactjs ecmascript-6 state

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

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

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

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

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

逐行(这可以并且使用setState):

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

3 个答案:

答案 0 :(得分:1)

不幸的是,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()用于返回一个新数组,旧值映射到一些新值。放弃.map()的回报意味着您使用了错误的循环范例。

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

答案 1 :(得分:1)

您正在尝试使用列表中的属性创建新的状态对象,并使用列表作为键从localStorage中提取数据。

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

    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);
    

答案 2 :(得分:0)

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

您需要遍历newData并使用computed property name语法:

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)