简体   繁体   中英

How to stop child component re-rendering on parent state change?

I have 400 textfield in App.tsx . Textfield code is present in child component textfield.tsx When I change textfield state from my parent component my child re renders 400 times

I want hi in console to print only 1 time instead of 400 . How can I solve this issue?

Sample Code:

App.ts

import { useState } from "react";
import MyTextField from "./components/textField.tsx/textField";

function App() {
   const [state, setState] = useState({} as any);
   const arr: any[] = []

   const fn = () => {
    for (var i = 0; i < 400; i++) {
     arr.push(i)
    }
   }
   function onChange(event: any) {
     const { name, value } = event.target;
     setState((prevState: any) => ({ ...prevState, [name]: value }));
   }
    return (
    <>
      {fn()}
      {
        arr.map((e) => <MyTextField variant='outlined' name={'n' + e} value={state['n'+ e]} onChange={onChange} />)
        }
    </>
   );

  }
 export default App;

textField.tsx

import { TextField, TextFieldProps, } from "@mui/material";
import React from "react";

const myClasses = ["custom1", "subvariant-hovered"] as const

type Props = Omit<TextFieldProps, "className" | "variant"> & {
  variant:  typeof myClasses[number] | TextFieldProps["variant"];
};

function MyTextField({ variant,name, ...rest }: Props) {
  return (
  <>
    {console.log('hi')}
     {myClasses.includes(variant as typeof ivpClasses[number]) ? (
       <TextField label="Search"  className={variant} {...rest}></TextField>
       ) : (
      <TextField label="Search" variant={variant as TextFieldProps["variant"]{...rest</TextField>
    )}
   </>
  )
 }
 export default React.memo(MyTextField);

Issue As soon as I enter w one time console.log print hi 400 times. I want hi to print only 1 time for each character.

On changing state of one text field console.log print hi 400 times for each character we typed

Code Sandbox : https://codesandbox.io/s/textfield-issue-m3i82e?file=/src/App.tsx

Right, so the issue is going deeper than what I have mentioned in my comment. It was true as well: for every re-render you were recreating the array and calling the function to populate it, which was causing the issue.

Additionally, your component state is an object that you append values to. Remember, when the state changes, it will re-render all the components that are hooked up to that state. And with every re-render it creates a new object, causing all of the inputs to re-render.

In order to sort this out, you could take a look at useCallback function as a wrapper around your state and for rendering your TextInput. I've created a sample here, which seems to be giving the output you want.

https://codesandbox.io/s/textfield-issue-forked-490ki2?file=/src/myTextField/myTextField.tsx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM