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
CodePudding user response:
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