Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I improve the react performance if I have many text inputs (Hooks) in a form?

The Problem

I have a form to send data through a api rest in React, the render and the writing on the form is very slow when I have about 80 text fields.

I'm using functional components with hooks to handle the input texts and Material-UI as UI framework. In a first try, I had a currying function to handle the values:

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

But the render process was really slow (because I was creating a function in every render), So I send the setter function as a prop, then it improves a little but not enough.

Actually the input response when I write a key in any input, it's about 500 ms.

What can I do to get a better performance?

The code was simplified for understanding purposes.

Sample code below:

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" />

My Input components:

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>
  )
}

All input values are must be in a component because I'm need to send them to a server with axios.

like image 301
TayLorWebK Avatar asked Jun 17 '19 02:06

TayLorWebK


People also ask

What makes Reactjs performance faster?

To optimize React rendering, you need to make sure that components receive only necessary props. It will let you control the CPU consumption and avoid over-rendering unnecessary features. The solution is to create a functional component that will collect all props and redistribute them to other components.

Which Hooks is used for React performance optimization?

2. useMemo() Hook. React allows developers to use a useMemo() hook, where we can use the optimization technique of Memoization.


1 Answers

It looks like the Material-UI Input component is a bit heavy.

I have a sample codesandbox here where I initialised around 1000 inputs. Initially it lagged and crashed.

To begin with I added a memo to the Input component. This memoizes all the Input components, triggering a new render only if one of its props has changed.

For a start just add a memo to your input component.

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>
  )
})

Note: If you have a custom setter like in your first case setValue = (setter) => (e) => { setter(e.target.value) }, you can wrap that in a useCallback to prevent multiple functions to be created for every render.

like image 158
johnny peter Avatar answered Oct 26 '22 09:10

johnny peter