Ввод не изменяется при изменении состояния реакции

#javascript #reactjs #react-hooks

#javascript #reactjs #реагирующие хуки

Вопрос:

У меня есть ввод выбора с 3 параметрами и 3 текстовыми вводами. Идея такова: я выбираю желаемое свойство (например: A), и только этот ввод будет доступен для пользователя, остальные будут отключены.

Затем я нажимаю кнопку «Рассчитать» ниже отключенных входных данных, и появляется вычисленное значение для этого ввода, основанное на вставленном мной свойстве (в данном случае, просто для упрощения, это значение всегда равно 123).).

 import React, { useState } from "react";
import "./styles.css";

export default function App() {
  const [models, setModels] = useState([
    { name: "A", value: undefined },
    { name: "B", value: undefined },
    { name: "C", value: undefined }
  ]);

  const onModelChange = (e) => {
    const { name, value } = e.target;
    let newModels = models;
    newModels[
      newModels.findIndex((model) => model.name === name)
    ].value = parseInt(value, 10);
    setModels(newModels);
  };

  const onCalculate = (modelName) => {
    let newModels = models;
    newModels[
      newModels.findIndex((model) => model.name === modelName)
    ].value = 123;
    console.log(newModels);
    setModels(newModels);
  };

  const [selectedOption, setSelectedOption] = useState("A");

  const handleChange = (e) => {
    setSelectedOption(e.target.value);
  };

  return (
    <div className="App">
      <select onChange={handleChange} value={selectedOption}>
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
      </select>
      <br />
      {models.map((model) => (
        <div key={model.name}>
          <input
            placeholder={model.name}
            name={model.name}
            label={model.name}
            width="100px"
            type="number"
            min="0"
            max="1000"
            value={model.value}
            onChange={onModelChange}
            disabled={selectedOption !== model.name}
          />
          <br />
          <button
            name="refresh"
            width="24px"
            height="24px"
            onClick={() => onCalculate(model.name)}
            disabled={selectedOption === model.name}
          >
            Calculate
          </button>
          <br />
        </div>
      ))}
    </div>
  );
}
  

Моя проблема в том, что значения во входных данных поступают из переменной состояния с именем «модели», и после того, как я нажимаю на Calculate, эта переменная изменяется, как вы можете видеть на консоли, но значение не отображается на отключенных входных данных.

Кто-нибудь знает, как это исправить?

Ссылка на codesandbox: https://codesandbox.io/s/affectionate-ives-uytgy?file=/src/App.js

Комментарии:

1. Вы изменяете состояние. Не изменять состояние — setModels([...newModels])

2. вы правы, большое вам спасибо!!

Ответ №1:

ПРОБЛЕМА

Вы изменяете массив состояний и обновляете его. React понятия не имеет, изменилось состояние или нет, поскольку вы передаете старую ссылку на setState.

РЕШЕНИЕ

  1. Сначала получите массив copy the state.
  2. Измените скопированную версию массива состояний.
  3. Обновите свое состояние новым обновленным измененным массивом.
  const onModelChange = e => {
    const { name, value } = e.target;
    let newModels = [...models];
    newModels[
      newModels.findIndex(model => model.name === name)
    ].value = parseInt(value, 10);
    setModels(newModels);
  };

  const onCalculate = modelName => {
    let newModels = [...models];
    newModels[
      newModels.findIndex(model => model.name === modelName)
    ].value = 123;
    setModels(newModels);
  };
  

Вы могли бы проверить аналогичную проблему в этом примере: — https://stackblitz.com/edit/react-osxmnr