UseState array Hooks return 在输入字段中的每个更改中的新对象

UseState array Hooks return a new object in every change in the input field

我正在为我正在处理的项目使用 React hooks。我遇到了一种情况,我想在 useState 挂钩中使用数组,但我不确定如何执行此操作。

我创建了一个 table,它根据一个月的天数动态更改列数。

我试过这样的事情:

const [inText, setInText] = useState([]);
const inputText = (e) => {
    setInText([...inText,{
        id:inText.length,
        value:e.target.value
    }]);
}

numberOfDays 是我计算的一个变量。它包含当月的天数。

const renderINP = () => {
    let td = [];
    for (let i = 1; i <= numberOfDays; i++) {
        td.push(<td key={i}><input type="text" onChange={inputText} /></td>);
    }
    return td;
};

这是将 table 呈现给浏览器的代码:

<table>
    <tbody>
        <tr className="work-days">
            <td>Working days</td>
            {renderINP()}
        </tr>
    </tbody>
</table>

我尝试用 cosole.log(inText) 捕捉 'inText'。当我在输入中键入内容时,例如 0,它会创建一个对象 {id: 0, value: '0'}。当我再次输入时,它会创建两个对象 {id: 0, value: '0'} 和 {id: 1, value: '0.'}。此外,当我删除某些内容时,它会创建另一个对象。

如何为每个输入创建一个对象,以及如何单独获取每个 inText 的值?例如,在第二个输入中获取 inText 的值,而不是所有对象的值。

useState 主要用于保存单个值。在这种情况下,您有一个对象数组并且想要更新单个对象的值。最好使用Reducer。

您可以阅读更多关于 useReducer

这应该能满足您的需求:

import React, { useReducer } from "react";

const App = () => {
  const reducer = (state, action) => {
    if (action.type === "ADD") {
      const newState = [...state];
      newState.push({ id: action.id, value: action.value });
      return newState;
    }

    if (action.type === "UPDATE") {
      const newState = [...state];
      const foundItem = newState.find((item) => item.id === action.id);
      foundItem.value = action.value;
      return newState;
    }
  };

  const initialState = [];

  const [state, dispatch] = useReducer(reducer, initialState);

  const numberOfDays = 7;

  const inputText = ({ id, value }) => {
    if (state.find((item) => item.id === id)) {
      dispatch({ type: "UPDATE", id, value });
    } else {
      dispatch({ type: "ADD", id, value });
    }

    console.log(state);
  };

  const renderINP = () => {
    let td = [];
    for (let i = 1; i <= numberOfDays; i++) {
      td.push(
        <td key={i}>
          <input
            type="text"
            onChange={(e) => inputText({ id: i, value: e.target.value })}
          />
        </td>
      );
    }
    return td;
  };

  return (
    <>
      <table>
        <tbody>
          <tr className="work-days">
            <td>Working days</td>
            {renderINP()}
          </tr>
        </tbody>
      </table>

      {JSON.stringify(state)}
    </>
  );
};

export default App;