使用 useContext 从数组中查找更新对象

Find an update object from an array in react using useContext

这是一个棘手的问题,我一直很难弄明白。首先,我使用 useContext 来创建全局状态。全局状态将保存并提供一个包含对象的数组。我有一个与每个对象一起呈现的表单。表单将有一个带有值的输入。 我的目标是能够找到对象并更新值。例如,Item1 中的输入会将“20”更新为正在输入的任何新数字,与 Item2 相同 现在发生了什么,每次我提交输入时,都会创建一个全新的数组而不是更新。我知道这是一种更简单的方法来实现这一点,但我需要这个数组处于全局状态。

这是我的沙箱 link https://codesandbox.io/s/muddy-wildflower-h5hhw?file=/src/App.js

谢谢!

您需要指定要更新的Array Item。首先,您需要指定需要更新的项目。为此,我通过 card props

传递了 value id
<Card
  name={value.name}
  value={value.Itemvalue}
  key={value.id}
  id={value.id}
/>

而且我已经使用 map 来更新特定的 object

const updatedData = value.map((obj) => {
    if (obj.id === id) {
        return { ...obj, Itemvalue: itemValue };
    } else return obj;
});
updateValue(updatedData);

这是工作 Link

问题是您要在表单更新的所有内容中添加新元素。这与您需要的不同。将 id 传递给更新函数,以便您可以更新该特定项目。

您的代码

  const addValue = (event) => {
    event.preventDefault();
    // You're not updating existing element, instead adding a new value.
    updateValue((prevItems) => [...prevItems, { Itemvalue: itemValue }]);
  };

// ...

    <form onSubmit={addValue}>
      <input
        type="text"
        name="price"
        Value={itemValue} // --> Typo here
        onChange={updateItemValue}
      />
      <button>Submit</button>
    </form>

您应该将 id 作为道具传递,而不是从上下文中获取。所以 <Add /> 确切地知道在哪里更新值。

更正代码

import React, { useContext, useState } from "react";
import { ValueContext } from "./ValueContext";

const Add = ({ id }) => { // --> Passing id from <Card /> 
  const [itemValue, setItemValue] = useState("");
  const [value, updateValue] = useContext(ValueContext);

  const updateItemValue = (event) => {
    setItemValue(event.target.value);
  };

  const addValue = (event) => {
    event.preventDefault();
    updateValue((prevItems) => {
      const index = prevItems.findIndex(x => x.id === id);
      const updatedItem = {
        ...prevItems[index],
        Itemvalue: itemValue
      }

      return [
        ...prevItems.slice(0, index),
        updatedItem, // --> Updating the item, instead of creating new one
        ...prevItems.slice(index + 1)
      ]
    });
  };
  return (
    <form onSubmit={addValue}>
      <input
        type="text"
        name="price"
        Value={itemValue}
        onChange={updateItemValue}
      />
      <button>Submit</button>
    </form>
  );
};

export default Add;