Огромный массив состояний реагирования с сотнями входов, медленные изменения состояния при изменении - PullRequest
0 голосов
/ 30 октября 2019

Я пытаюсь создать большую форму React, но каждый вход в форме является сложным и имеет сложное состояние. Я сохраняю состояние всех входов в компоненте parent, и каждый вход оборачивается компонентом child. У меня есть массив состояний в родительском, который содержит текущее значение состояния для всех входных элементов. В настоящее время каждый раз, когда на входе присутствует onChange, я пытаюсь сбросить весь массив состояний в родительском элементе с помощью setState(). Это было нормально с 5 входами, но как только я поднялся выше этого уровня (около ста входов), я начал замечать серьезное отставание в программе. Обратите внимание: : программа также позволит вам переставить входы delete и add, поэтому состояние должно учитывать эти изменения Т.е. первый вход может поменяться местами со вторым входом или быть вставлен сразу после 10-го входа.

Моя цель - найти способ оптимизировать производительность этого onChange. В конечном счете, мне не нужно, чтобы данные были в компоненте parent, мне просто нужно собрать значения для входных данных, когда я нажимаю save внизу страницы.

Просто повторюсь, у меня есть два компонента.

  1. Родительский компонент

  2. Дочерний компонент

Дочерний компонент - это, по сути, input, где пользователи могут писать сотни строк текста.

Родительский компонент содержит 100 дочерних элементов и по сути выглядит следующим образом:

export default function Parent(props) {
  const [state, setState] = useState(createDummyData());
  useEffect(() => {});



  const onInputChange = (value, index) => {
    var tempValue = [...state];
    tempValue[index] = value;
    setState(tempValue);
  };

  return (
    <>
      <div style={{ display: "flex", flexDirection: "column" }}>
        {state.map((item, index) => (
          <Child
            value={state[index].content}
            index={index}
            onChange={onInputChange}
          />
        ))}
        <button style={{backgroundColor: "red"}}>save input data</button>
      </div>
    </>
  );
}

Дочерний компонент выглядит следующим образом

export default function Child(props) {
  useEffect(() => {});

  const onChange = event => {
    props.onChange(event.target.value, props.index);
  };

  return (
    <>
      <input value={props.value} onChange={onChange} />
    </>
  );
}

Я не нашелпростой способ обойти это. Некоторые, кажется, предлагают использовать Redux, другие, кажется, используют комбинацию useMemo и useEffect, чтобы предотвратить повторное рендеринг. Ваша помощь будет принята с благодарностью.

Одна вещь, которую я заметил, это то, что, если я пытаюсь сохранить индивидуальное состояние внутри дочерних компонентов, они визуализируют onChange намного быстрее. Вероятно, это связано с тем, что не нужно каждый раз устанавливать setState для родительского массива состояний. Если возможно, я бы хотел иметь возможность просто просмотреть и просмотреть состояние дочерних узлов, когда я нажму кнопку Сохранить. Буду ли я использовать ref в этом случае? Можно ли сделать это без ссылки?

Я также хотел бы ИЗБЕГАТЬ, используя onBlur() только для целей этого проекта

Кодовые окна скопированы ниже для справки: https://codesandbox.io/s/cocky-knuth-jm8n6?fontsize=14

1 Ответ

0 голосов
/ 30 октября 2019

Создан пример с аналогичными функциональными компонентами и фиктивными данными:

https://codesandbox.io/s/recursing-cdn-q4vx0

Необходимо создать дочерний компонент с локальным состоянием элемента и синхронизировать с основным массивом. Добавлены Delete и Add.

Работа с массивами объектов в качестве образца.

...