如何将 excel sheet 中的值粘贴到 table 并将其存储在 React 的状态中?

How to paste vaues from excel sheet to table and store it in state in React?

我在 React 中创建了一个 table,我必须将 Excel sheet 中的值粘贴到那里并将它们存储在一个状态中。我尝试了 onPaste 和 onInput 事件,但它只将 sheet 的最后一个值存储到状态中。

function App() {
  const [label, setlabel] = useState({ labels: ["Lat [deg]", "Long [deg]"] });
  const [inputvalue, setinputvalue] = useState({
    inputs: [
      { "Lat [deg]": "", "Long [deg]": "" },
      { "Lat [deg]": "", "Long [deg]": "" },
    ],
  });

  const handlePaste = (index, elm, e, i) => {
    return parse(e);
  };

  const handlePaste1 = (index, elm, e, i) => {
    const newList4 = inputvalue.inputs.map((item, i) => {
      if (index === i) {
        const updatedItem = {
          ...item,
          [elm]: e.target.value,
        };
        console.log(updatedItem);
        return updatedItem;
      }
      return item;
    });
    console.log("newList4", newList4);

    setinputvalue((prevData) => ({
      ...prevData,
      inputs: newList4,
    }));

    console.log("Input Value", inputvalue);
  };
  return (
    <table>
      <tr className="text-center">
        {label.labels.map((elm, ind) => {
          return (
            <th
              style={{
                width: "150px",
                border: "1px solid black",
                backgroundColor: labelcolor.labelcolors[ind].color,
              }}
            >
              {elm}
            </th>
          );
        })}
      </tr>
      {inputValues.inputs.map((res, index) => {
        return (
          <tr key={index}>
            {label.labels.map((elm, i) => {
              return (
                <td
                  style={{
                    width: "150px",
                    minHeight: "30px",
                    border: "1px solid black",
                    borderRadius: "0px",
                    wordWrap: "break-word",
                  }}
                >
                  <input
                    onInput={(e) => {
                      handlePaste1(index, elm, e, i);
                    }}
                    onPaste={(e) => {
                      handlePaste(index, elm, e, i);
                    }}
                    type="textbox"
                    className="text-center inputtextbox"
                  />
                </td>
              );
            })}
          </tr>
        );
      })}
    </table>
  );
}

export default App;

在 handlePaste1 函数中,我在不同的元素中设置状态,即 Lat [deg] 和 Long [deg]。但是我只得到 inputValue 状态中的最后一个值。

这是输入:-

所以这里的输入是 1 2 3 4

//The value in inputValue state I want:-

inputs: [
          { "Lat [deg]": "1", "Long [deg]": "2" },
          { "Lat [deg]": "3", "Long [deg]": "4" },
        ],

//The value in inputValue state I'm getting:-

inputs: [
          { "Lat [deg]": "", "Long [deg]": "" },
          { "Lat [deg]": "", "Long [deg]": "4" },
        ],

   

Codesandbox link:- Click here for live code

问题

看起来这个问题与在单个渲染周期内对多个状态更新进行排队有关。似乎每个被粘贴的单元格都会触发它自己的状态更新,并且由于每个更新都是从渲染周期的状态值开始的,更新被排队,每个后续更新都会覆盖以前的更新。最后一次更新是您看到的那个,例如您只看到第四个单元格已更新。

解决方案

handlePaste1 转换为使用功能状态更新,使其从之前的状态更新,而不是之前渲染周期的状态。

const handlePaste1 = (index, elm, e, i) => {
  setinputvalue((inputvalue) => ({
    ...inputvalue,
    inputs: inputvalue.inputs.map((item, i) =>
      index === i
        ? {
            ...item,
            [elm]: e.target.value
          }
        : item
    )
  }));
};