ReactJS форма производительности проблема обновления массива объекта в состоянии - PullRequest
1 голос
/ 24 апреля 2020

У меня есть динамическая c форма, сгенерированная из массива, я использую форму hook и setState для управления ею. Я столкнулся с проблемой производительности: входные данные отстают. Я ожидаю, что это будет гладко, по крайней мере, на данный момент государство не велико.

const guests = ["adult", "child"];
const dynamicInputsDefaultState = guests.map((v, i) => ({
  [`fname#${i}`]: {
    value: ""
  }
}));

const useFormHook = () => {
  const [dynamicInputs, setDynamicInputs] = useState(dynamicInputsDefaultState);
  const handleInputChange = (e, guestIndex) => {
    if (guestIndex !== undefined) {
      const nextDynamicInputs = dynamicInputs.map((v, i) =>
        i === guestIndex
          ? {
              ...v,
              [e.target.name]: {
                ...v[e.target.name],
                value: e.target.value
              }
            }
          : v
      );

      setDynamicInputs(nextDynamicInputs);
    }
  };

  return {
    dynamicInputs,
    handleInputChange
  };
};

https://codesandbox.io/s/vibrant-ride-fmp2b?file= / src / App. js: 539-556

Я застрял в поиске проблемы

1 Ответ

0 голосов
/ 24 апреля 2020

По сути, это потому, что вы используете Guest в качестве компонента, и каждый раз, когда изменяется вход, он должен повторяться, потому что входное значение dynamicInputs передается как пропеллер.

Если это нужно использовать таким образом, лучше не абстрагировать его таким образом, а просто поместить содержимое Guest в ваш возврат в пределах App ИЛИ деконструировать formHook изнутри Guest и полностью избавьтесь от его реквизита.

Также обратите внимание, что Guest даже не должен быть компонентом, он может просто использоваться как функция, которая облегчит проблему (см. Вариант № 3 ниже).

Вариант № 1. Объединение Guest в App

return (
  <div className="App">
    <div>
      {guests.map((guest, i) => {
        return (
          <div key={i}>
            <input
              name={`fname#${i}`}
              onChange={e => handleInputChange(e, i)}
              value={dynamicInputs[i][`fname#${i}`].value}
              type="text"
              placeholder={`${i} fname`}
            />
          </div>
        );
      })}
    </div>
  </div>
);

Option # 2 Использование formHook в пределах Guest

export default function App() {
  const guests = ["adult", "child"];
  const Guests = () => {
    const { dynamicInputs, handleInputChange } = formHook();
    return (
      <div>
      {guests.map((guest, i) => {
        return (
          <div key={i}>
            <input
              name={`fname#${i}`}
              onChange={e => handleInputChange(e, i)}
              value={dynamicInputs[i][`fname#${i}`].value}
              type="text"
              placeholder={`${i} fname`}
            />
          </div>
        );
      })}
      </div>
    );
  };
  return (
    <div className="App">
      <Guests />
    </div>
  );
}

Option # 3 Использование простой функции вместо функционального компонента

export default function App() {
  const { dynamicInputs, handleInputChange } = formHook();
  const guests = ["adult", "child"];

  const guestFunction = () => {
    return (
      <div>
      {guests.map((guest, i) => {
        return (
          <div key={i}>
            <input
              name={`fname#${i}`}
              onChange={e => handleInputChange(e, i)}
              value={dynamicInputs[i][`fname#${i}`].value}
              type="text"
              placeholder={`${i} fname`}
            />
          </div>
        );
      })}
      </div>
    );
  };
  return (
    <div className="App">
      {guestFunction()}
    </div>
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...