Пытаюсь сделать приложение, рассчитывающее налоги и скидки, но не могу понять, как наладить связь между штатами. Поскольку переключение между входами будет непрерывным, я назначил событие onkeyup для каждого почтового ящика. Каждый раз, когда вызывается это событие, вызываемая функция должна выполнять необходимые действия. Например, когда я ввожу значения количества и unitPrice, он умножает два значения и присваивает их значению goodsServiceAmt. В приложении также есть возможность добавлять и удалять строки. Расчет каждой строки должен быть сам по себе. Я пытался сделать это с помощью функции handleQuantity, состояние обновляется, но значение на входе не меняется.


const App = () => {
  const [mainData, setMainData] = useState([
    {
      id: 1,
      quantity: "",
      unitPrice: "",
      discRate: "",
      discAmt: "",
      kdvAmt: "",
      kdvRate: "",
      goodsServiceAmt: "",
    },
  ]);

  const deleteRow = (e, i) => {
    e.preventDefault();
    const newArr = [...mainData];
    console.log(i);
    newArr.splice(i, 1);
    setMainData(newArr);
  };

  const handleChangeInput = (e, i) => {
    const values = [...mainData];
    values[i][e.target.name] = e.target.value;
    setMainData(values);
  };

  const addRow = () => {
    const id = mainData.length ? mainData.length + 1 : 0;
    console.log(id);
    setMainData([
      ...mainData,
      {
        id,
        quantity: "",
        unitPrice: "",
        discRate: "",
        discAmt: "",
        kdvAmt: "",
        kdvRate: "",
        goodsServiceAmt: "",
      },
    ]);
  };

  const handleQuantity = (e, i) => {
    const deger = [...mainData];
    deger[i].unitPrice = e.target.value;
    setMainData(deger);
  };

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {mainData.map((v, i) => (
        <form key={i} style={{ display: "flex" }}>
          <span style={{ width: "50px", height: "50px" }}>{v.id}</span>
          <div className="input-cont">
            <label htmlFor="quantity">quantity</label>
            <input
              type="text"
              name="quantity"
              value={mainData.quantity}
              onChange={(e) => handleChangeInput(e, i)}
              onKeyUp={(e) => handleQuantity(e, i)}
            />
          </div>
          <div className="input-cont">
            <label htmlFor="unitPrice">unitPrice</label>
            <input
              type="text"
              name="unitPrice"
              value={mainData.unitPrice}
              onChange={(e) => handleChangeInput(e, i)}
            />
          </div>
          <div className="input-cont">
            <label htmlFor="discRate">discRate</label>
            <input
              type="text"
              name="discRate"
              value={mainData.discRate}
              onChange={(e) => handleChangeInput(e, i)}
            />
          </div>
          <div className="input-cont">
            <label htmlFor="discAmt">discAmt</label>
            <input
              type="text"
              name="discAmt"
              value={mainData.discAmt}
              onChange={(e) => handleChangeInput(e, i)}
            />
          </div>
          <div className="input-cont">
            <label htmlFor="kdvRate">kdvRate</label>
            <input
              type="text"
              name="kdvRate"
              value={mainData.kdvRate}
              onChange={(e) => handleChangeInput(e, i)}
            />
          </div>
          <div className="input-cont">
            <label htmlFor="kdvAmt">kdvAmt</label>
            <input
              type="text"
              name="kdvAmt"
              value={mainData.kdvAmt}
              onChange={(e) => handleChangeInput(e, i)}
            />
          </div>
          <div className="input-cont">
            <label htmlFor="goodsServiceAmt">goodsServiceAmt</label>
            <input
              type="text"
              name="goodsServiceAmt"
              value={mainData.goodsServiceAmt}
              onChange={(e) => handleChangeInput(e, i)}
            />
          </div>
          <button onClick={(e) => deleteRow(e, i)}>delete</button>
        </form>
      ))}
      <button onClick={addRow}>add row</button>
      <button onClick={() => console.log(mainData)}>clg</button>
    </div>
  );
};

export default App;
0
poena 5 Дек 2020 в 18:31

2 ответа

Лучший ответ

Это происходит потому, что вы обращаетесь к данным во входных данных как к объекту, но в вашем useState это массив.

Измените состояние использования на:

const [mainData, setMainData] = useState({
      id: 1,
      quantity: "",
      unitPrice: "",
      discRate: "",
      discAmt: "",
      kdvAmt: "",
      kdvRate: "",
      goodsServiceAmt: "",
});

Или измените значение во входных данных на:

value={mainData[0].quantity}
2
Filipe 5 Дек 2020 в 15:53

Поскольку ваши mainData - это массив, когда вы выполняете это присвоение входному значению mainData.quantity, вы фактически передаете undefined, преобразовывая входные данные в неконтролируемые. Из-за этого неконтролируемого ввода создается впечатление, что вы получаете данные из состояния, но на самом деле это не так. Поэтому вам нужно изменить эти вызовы на mainData[i].quantity, чтобы правильно получать данные.

И в качестве примечания, вы все еще можете использовать функцию onChange для обработки количества

2
MaCadiz 5 Дек 2020 в 16:00