what is the better way to reduce re-rendering of whole component when using multiple states

Viewed 45

This question is to understand which is the best option out of many to get a form data with multiple inputs. i have read many blogs and stackoverflow answers, still not satisfied with the results.

I have a component with a filter form having n number of input fields. in the same components, there is a table which displays the data as per the filters.

  1. First method i tried, is updating n states on changes of n input fields. this is re-rendering the whole component. (it is unnecessary since i need to filter only when the filter button is clicked)

  2. second method, created a controlled input component and in parent component under forms added it as child. now changes in input fields are only updated in that component. when filter button in parent component is clicked, i use ref to get the input field data.

Parent component

const formRef = useRef()

const handleFilter= () =>{
  //here all i need to do is get the input data..no dom modification
  console.log(formRef.current.a.value)
  console.log(formRef.current.b.value)
  console.log(formRef.current.c.value)
  //call the api to get the data based on above queries and display in the table
}

<parent>
  <Form ref={formRef}>
    <CustomInput input name='a'/>
    <CustomInput input name='b'/>
    <CustomInput input name='c'/>
    <Button onClick={handleFilter}> Filter </Button>
  </Form>
  <Table >
    Data displayed as per above form filter only when filter button clicked
  </Table>
</parent>

Child component ( CustomInput ):

const CustomInput = (props) =>{

  const [value, setValue] = useState('')

  return(
    <input name={props.name}
    value={value}
    onChange = {(e) => setValue(e.target.value)}/>
  )
}
  1. third method to stop full component re-rendering is : Make Form as a separate component, in that call the CustomChild input component and call the Form component in parent. here i would have to lift up the state two levels

  2. i can use context hook or redux or whatever tool is available.

Out of these 4 , i found method 2 is less code, easy to understand and maintain.

So can i go with it ?. does this implementation follow the react rules (although this 2nd method helps me to reduce the re-render to only one input component at a time ) ?

Or is there a better way than this ? All opinions are welcomed

1 Answers

I started this as a response to your comment, but figured it should be a full answer.

I see where you're coming from, and you have some good points, but I definitely think you're prematurely optimizing. React is built for things like re-rendering on every keystroke. I've used large forms with controlled components without any performance issues. On re-render, React keeps a virtual DOM, and only modifies the actual DOM when needed.

Your idea of using a ref to get the form state is a neat idea, but you're trading off development and conceptual complexity for, at best, an incredibly slim performance benefit. Unless you have a massive parent component with hundreds/thousands of complex children, you're much better off just following standard practices.

If you feel very strongly about this, you could use Redux in each of the children to modify a form state, and directly extract the state on form submission (as opposed to having the parent subscribe to the state with useSelector). The children would us useSelector to only rerender when their individual slice of state is changed.

A quote I like, though a bit cliche at this point, is “Premature optimization is the root of all evil” by Donald Knuth. Having easy to reason about and maintain code is a huge consideration, and like you said in the comments, the re-renders are not causing you any problems right now. And I don't think that they ever realistically will.

Related