【问题标题】:React 17.0.1 Form onChange skips the last numberReact 17.0.1 Form onChange 跳过最后一个数字
【发布时间】:2021-04-17 09:24:28
【问题描述】:

我有输入类型 number ,它有一个非常简单的 onChange 函数,当输入一个值时,最后一个数字被遗漏了

例子:

如果输入框输入99,只记录9,输入框输入2523时,记录252,跳过最后一个数字

这里是sandbox link

onChange 函数内部

const handleRequestingCost = (e, index) => {
setCostsFormValues({
  ...costsFormValues,
  [e.target.name]: [e.target.value]
});

for (const key in costsFormValues) {
  const mappedData = {
    [key]: costsFormValues[key][0]
  };
  mappedDataArray.push(mappedData);
  const list = [...row];
  const item = list[index];
  if (item) {
    item.requestingCost = mappedDataArray;
    setRow(list);
  }
}
...

我在这里缺少什么?或者这是不是不好的做法?

【问题讨论】:

    标签: javascript node.js reactjs forms express


    【解决方案1】:

    setState 是异步的。所以你在更新之前正在阅读costsFormValues

    import "./styles.css";
    import { Button, Form } from "react-bootstrap";
    import React, { useState } from "react";
    
    export default function App() {
      const [costsFormValues, setCostsFormValues] = useState({});
      const [row, setRow] = useState([
        {
          index: 5399,
          name: "user name",
          quantity: "1000",
          remainingQty: 2000,
          requestingCost: [],
          budgetedCost: [
            {
              key: "Labour Cost",
              value: 176
            },
            {
              key: "Material Cost",
              value: 890
            }
          ],
          amountForQuantity: [
            {
              key: "Labour Cost",
              value: 150
            },
            {
              key: "Material Cost",
              value: 570
            }
          ]
        }
      ]);
    
      const handleRequestingCost = (e, index) => {
        const mappedDataArray = [];
      
        setCostsFormValues({
          // set all cost value in each array
          ...costsFormValues,
          [e.target.name]: [e.target.value]
        });
        const updatedFormValues = {     // added this local variable which holds latest value update
          // set all cost value in each array
          ...costsFormValues,
          [e.target.name]: [e.target.value]
        };
        for (const key in updatedFormValues) {
          // loop each array and merge into one object
          const mappedData = {
            [key]: updatedFormValues[key][0]
          };
          mappedDataArray.push(mappedData);
          const list = [...row];
          const item = list[index];
          if (item) {
            item.requestingCost = mappedDataArray;
            setRow(list);
          }
        }
        console.log(updatedFormValues);
      };
    

    【讨论】:

      【解决方案2】:

      请尝试对局部变量进行更改,而不是直接设置状态对象,因为在 setState() 调用后大约需要 300-500 毫秒才能更新;因为它会为性能优化创建队列。

      请参考代码sn-p:

       const handleRequestingCost = (e, index) => {
          const mappedDataArray = [];
          let TempValue = {};
      
          TempValue = {
            ...TempValue,
            [e.target.name]: [e.target.value]
          };
          for (const key in TempValue) {
            // loop each array and merge into one object
            const mappedData = {
              [key]: TempValue[key][0]
            };
            mappedDataArray.push(mappedData);
            const list = [...row];
            const item = list[index];
            if (item) {
              item.requestingCost = mappedDataArray;
              setRow(list);
            }
          }
          console.log(TempValue);
        };
      

      【讨论】:

        【解决方案3】:

        由于setState 是异步的,你应该在改变它之后使用该值,这就是为什么我们有useEffect 钩子来代替它

         const handleRequestingCost = (e, index) => {
            const mappedDataArray = [];
            setCostsFormValues({
              // set all cost value in each array
              ...costsFormValues,
              [e.target.name]: [e.target.value]
            });
            for (const key in costsFormValues) {
              // loop each array and merge into one object
              const mappedData = {
                [key]: costsFormValues[key][0]
              };
              mappedDataArray.push(mappedData);
              const list = [...row];
              const item = list[index];
              if (item) {
                item.requestingCost = mappedDataArray;
                setRow(list);
              }
            }
          };
          useEffect(() => {
            console.log(costsFormValues);
          }, [costsFormValues]);
        

        控制台会显示正确的值,但要小心我的 sn-p,你的 handleRequestCostcostsFormValues 做一些事情,你也应该把它传递给 useEffect

         const handleRequestingCost = (e, index) => {
            setCostsFormValues({
              // set all cost value in each array
              ...costsFormValues,
              [e.target.name]: [e.target.value]
            });
          };
          useEffect(() => {
            const mappedDataArray = [];
            console.log(costsFormValues);
            for (const key in costsFormValues) {
              // loop each array and merge into one object
              const mappedData = {
                [key]: costsFormValues[key][0]
              };
              mappedDataArray.push(mappedData);
              const list = [...row];
              const item = list[index];
              if (item) {
                item.requestingCost = mappedDataArray;
                setRow(list);
              }
            }
          }, [costsFormValues]);
        

        类似这样的东西,但有一个 index 我还没有从你的逻辑中得到

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-02-10
          • 2016-01-10
          • 2018-08-03
          • 2016-12-18
          • 1970-01-01
          • 2023-02-04
          • 2023-03-17
          相关资源
          最近更新 更多