Как я могу улучшить производительность реакции, если у меня есть много текстовых вводов (хуков) в форме? - PullRequest
0 голосов
/ 17 июня 2019

Проблема

У меня есть форма для отправки данных через api rest в React, рендер и запись в форму очень медленные, когда у меня есть около 80 текстовых полей.

Я использую функциональные компоненты с крючками для обработки ввода текста и Material-UI в качестве инфраструктуры пользовательского интерфейса. В первой попытке у меня была функция карри для обработки значений:

setValue = (setter) => (e) => { setter(e.target.value) }

Но процесс рендеринга был действительно медленным (потому что я создавал функцию при каждом рендеринге), поэтому я посылаю функцию сеттера в качестве опоры, затем она немного улучшается, но не достаточно.

На самом деле ответ ввода, когда я записываю ключ в любой ввод, составляет около 500 мс.

Что я могу сделать, чтобы улучшить производительность?

Код был упрощен для понимания.

Пример кода ниже:

const [input1, setInput1] = useState('')
const [input2, setInput2] = useState('')
const [input3, setInput3] = useState('')
.
.
.
const [input80, setInput80] = useState('')

// render the Inputs
<Input value={input1} setter={setInput1} text="Some label text" />
<Input value={input2} setter={setInput2} text="Some label text" />
<Input value={input3} setter={setInput3} text="Some label text" />
.
.
.
<Input value={input80} setter={setInput80} text="Some label text" />

Мои компоненты ввода:

const Input = ({
  value, setter, text, type = 'text'
}) => {
  const handleChange = (e) => {
    const { value: inputValue } = e.target
    setter(inputValue)
  }
  return (
    <Grid>
      <TextField
        fullWidth
        type={type}
        label={text}
        value={value}
        onChange={handleChange}
        multiline={multiline}
      />
    </Grid>
  )
}

Все входные значения должны быть в компоненте, потому что мне нужно отправить их на сервер с axios.

1 Ответ

0 голосов
/ 17 июня 2019

Похоже, что компонент Material-UI Input немного тяжел.

У меня есть образец кода и поле здесь , где я инициализировал около 1000 входов.Первоначально он отставал и разбился.

Для начала я добавил memo к компоненту Input.Это запоминает все компоненты Input, вызывая новый рендеринг, только если один из его реквизитов изменился.

Для начала просто добавьте memo к вашему компоненту ввода.

import React, { memo } from 'react';

const Input = memo(({
  value, setter, text, type = 'text'
}) => {
  const handleChange = (e) => {
    const { value: inputValue } = e.target
    setter(inputValue)
  }
  return (
    <Grid>
      <TextField
        fullWidth
        type={type}
        label={text}
        value={value}
        onChange={handleChange}
        multiline={multiline}
      />
    </Grid>
  )
})

Примечание: Если у вас есть пользовательский установщик, как в первом случае setValue = (setter) => (e) => { setter(e.target.value) }, вы можете заключить его в useCallback, чтобы предотвратить создание нескольких функций для каждого рендера.

...