我如何在React Hooks中更新对象数组中的状态onchange

时间:2019-05-05 00:38:21

标签: javascript reactjs react-hooks

我已经检索了使用useState存储在对象数组中的数据,然后将这些数据输出到表单字段中。现在,我希望能够在键入时更新字段(状态)。

我似乎有一些例子,人们在更新数组中属性的状态,但从未更新对象数组中的状态,所以我不知道该怎么做。我已经将对象的索引传递给了回调函数,但是我不知道如何使用它来更新状态。


// sample datas structure
const datas = [
    {
      id:   1,
      name: 'john',
      gender: 'm'
    }
    {
      id:   2,
      name: 'mary',
      gender: 'f'
    }
]

const [datas, setDatas] = useState([]);

const updateFieldChanged = index => e => {

    console.log('index: ' + index);
    console.log('property name: '+ e.target.name);

        setData() // ??
}

return (
    <React.Fragment>
        { datas.map( (data, index) => {
              <li key={data.name}>
                <input type="text" name="name" value={data.name} onChange={updateFieldChanged(index)}  />
              </li>
          })
        }
    </React.Fragment>
)

6 个答案:

答案 0 :(得分:1)

这是您的操作方式:

// sample datas structure
/* const datas = [
    {
      id:   1,
      name: 'john',
      gender: 'm'
    }
    {
      id:   2,
      name: 'mary',
      gender: 'f'
    }
] */ // make sure to set the default value in the useState call (I already fixed it)

const [datas, setDatas] = useState([
    {
      id:   1,
      name: 'john',
      gender: 'm'
    }
    {
      id:   2,
      name: 'mary',
      gender: 'f'
    }
]);

const updateFieldChanged = index => e => {

    console.log('index: ' + index);
    console.log('property name: '+ e.target.name);
    let newArr = [...datas]; // copying the old datas array
    newArr[index] = e.target.value; // replace e.target.value with whatever you want to change it to

    setDatas(newArr); // ??
}

return (
    <React.Fragment>
        { datas.map( (data, index) => {
              <li key={data.name}>
                <input type="text" name="name" value={data.name} onChange={updateFieldChanged(index)}  />
              </li>
          })
        }
    </React.Fragment>
)

答案 1 :(得分:1)

您可以通过将旧数组映射到一个新数组,并在此过程中将要更改的内容交换为更新的内容,而无需进行任何更改。

#

答案 2 :(得分:0)

这就是我要做的:

const [datas, setDatas] = useState([
  {
    id: 1,
    name: "john",
    gender: "m",
  },
  {
    id: 2,
    name: "mary",
    gender: "f",
  },
]);

const updateFieldChanged = (name, index) => (event) => {
  let newArr = datas.map((item, i) => {
    if (index == i) {
      return { ...item, [name]: event.target.value };
    } else {
      return item;
    }
  });
  setDatas(newArr);
};

return (
  <React.Fragment>
    {datas.map((data, index) => {
      <li key={data.name}>
        <input
          type="text"
          name="name"
          value={data.name}
          onChange={updateFieldChanged("name", index)}
        />
      </li>;
      <li key={data.gender}>
        <input
          type="text"
          name="gender"
          value={data.gender}
          onChange={updateFieldChanged("gender", index)}
        />
      </li>;
    })}
  </React.Fragment>
);

答案 3 :(得分:0)

你甚至不需要使用索引(除了你想要的键),也不需要复制旧的数据数组,甚至可以内联或者只传递数据作为参数,如果你喜欢 updateFieldChanged 不是排队。这样做很快:

  const initial_data = [
    {
      id: 1,
      name: "john",
      gender: "m",
    },
    {
      id: 2,
      name: "mary",
      gender: "f",
    },
  ];

  const [datas, setDatas] = useState(initial_data);

  return (
    <div>
      {datas.map((data, index) => (
        <li key={index}>
          <input
            type="text"
            value={data.name}
            onChange={(e) => {
              data.name = e.target.value;
              setDatas([...datas]);
            }}
          />
        </li>
      ))}
    </div>
  );
};

答案 4 :(得分:0)

setDatas(datas=>({
   ...datas,
   [index]: e.target.value
}))

index 为目标位置,e.target.value 为新值

答案 5 :(得分:-1)

基于@Steffan,因此按照您的方式使用:

const [arr,arrSet] = useState(array_value);
...
let newArr = [...arr];
  arr.map((data,index) => {
    newArr[index].somename= new_value;
  });
arrSet(newArr);

使用 useEffect 检查新的 arr 值。