简体   繁体   English

如何从setState中的数组中选择特定对象?

[英]How to select a specific object from array inside setState?

 class Example extends React.Component{ constructor(props){ super(props); this.state = { array: [{n: 0}, {n: 1}, {n: 2}] } } selectObjectFromArray = index => { this.setState({ array: //??? }) } 

We only know the index, where we want to edit the object in the array. 我们只知道索引,我们要在数组中编辑对象。 We can't do like this.state.array[1] = ... , and we can't do setState({array[1]:... . I was considered about spread like: array: [...this.state.array, , but in this situation, we can't set, where we want to edit. So what can we do in this situation? 我们不能像this.state.array[1] = ... ,也不能像setState({array[1]:...我被认为是关于传播的: array: [...this.state.array,但是在这种情况下,我们无法设置要编辑的位置,那么在这种情况下我们该怎么办?

To update a state-array, you have to create a copy of it, update some entries and push the new array back to the state. 要更新状态数组,您必须创建它的副本,更新一些条目,然后将新数组推回该状态。

Here's a simple example where the button updates the last item: 这是一个简单的示例,其中的按钮更新了最后一项:

import React from "react";
import ReactDOM from "react-dom";

class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      array: [{ n: 0 }, { n: 1 }, { n: 2 }]
    }
  }

  render() {
    return <div>

    <ul> {
      this.state.array.map((item,key) => {
        return <li key={key} >{item.n} </li>
      })
    }
    </ul>


    <button onClick={this.updateLast}>update first</button>
    </div>
  }

  updateLast = () => {
    this.selectObjectFromArray(this.state.array.length -1 )
  }

  selectObjectFromArray = index => {
    // create a copy of the array        
    let newArr = this.state.array;

    // the item variable is optional but hope clarifies how this works
    let item = newArr[index];    
    item = {
      n: item.n * 2
    }

    newArr[index] = item;

    // update the state with the new data
    this.setState({
      array: newArr
      })
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Example />, rootElement);

This working example can also be found here: https://codesandbox.io/s/o4x6mpnozq 也可以在以下位置找到该工作示例: https : //codesandbox.io/s/o4x6mpnozq

We only know the index, where we want to edit the object in the array 我们只知道索引,我们要在数组中编辑对象

Given a knownIndex 给定一个knownIndex

this.setState({
  array:
    [ ...this.state.array.slice (0, knownIndex)  // <-- items up to the index
    , someUpdate(this.state.array[knownIndex]))  // <-- updated object
    , ...this.state.array.slice (knownIndex + 1) // <-- items after the index
    ]
})

Another way you could do it is using the Array .map function. 您可以执行的另一种方法是使用Array .map函数。 Let's also make it a generic function 我们也将其设为通用函数

const updateAtIndex = (xs, i, f) =>
  xs .map ((x, j) => i === j ? f (x) : x)

In your component, you can use it like this 在组件中,您可以像这样使用它

this.setState ({
  array: updateAtIndex (this.state.array, knownIndex, f)
})

Where f is some function to update the object, for example 其中f是用于更新对象的某些函数,例如

// returns a new object with the n property doubled
const f = obj =>
  ({ n: obj.n * 2 })

When writing generic functions, I like to make them a little more robust. 在编写泛型函数时,我希望使它们更健壮。 If you use this technique in your program, I would recommend a few changes to the functions above. 如果您在程序中使用此技术,建议对上述功能进行一些更改。 These changes communicate the parameter types more effectively and allow the reader to better infer the functions return type. 这些更改可以更有效地传达参数类型,并使读者可以更好地推断函数的返回类型。

const identity = x =>
  x

const updateAtIndex = (xs = [], i = 0, f = identity) =>
  xs .map ((x, j) => i === j ? f (x) : x)

const f = ({ n = 0 }) =>
  ({ n: n * 2 })

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

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