I have been trying to avoid re-rendering the child components (InputBox component) if the props are not changing but below code is not working as expected. How can I fix it ? How to avoid re-rendering InputBox component this as name is same but memoizedCallbacks is not memoized
<InputBox name={"test"} handleCb={memoizedCallback} id="name" /> <body> <div id="root"></div> <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script> <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/[email protected]/babel.js"></script> <script type="text/babel"> // child var InputBoxSet = new Set(); const InputBox = React.memo(function InputBox({ name, handleCb }) { // should not re-render on name or handlerCB change console.log('%c InputBox renders', 'color: orange; font-weight: bold;'); InputBoxSet.add(name); InputBoxSet.add(handleCb); console.log('%c InputBoxSet', 'color: orange; font-weight: bold;',InputBoxSet); return <input value={name} onChange={handleCb} id="name" />; }); // parent let mySet = new Set(); // to check if the callback function is new each it re-renders const Greeting = React.memo(function Greeting(props) { console.log('%c greeting renders!', 'color: green; font-weight: bold;'); const [name, setName] = React.useState(""); const handleChange = (event) => { console.log("handleChange"); setName(event.target.value); }; // despite memoizing callback , the memoize callback function is // getting created new each time and hence causing the re-rendering of child const memoizedCallback = React.useCallback( (event) => { console.log('%c event', 'color: red; font-weight: bold;'); handleChange(event); // doesn't call originial function unless event is changed }, [event] ); mySet.add(memoizedCallback); console.log('%c mySet', 'color: green; font-weight: bold;',mySet); return ( <div> <form> <label htmlFor="name">Name: </label> <input value={name} onChange={memoizedCallback} id="name" /> {/* how to avoid re-rendering this */} <InputBox name={"test"} handleCb={memoizedCallback} id="name" /> </form> {name ? <strong>Hello {name}</strong> : "Please type your name"} </div> ); }, areEqual); function areEqual(prevProps, nextProps) { return prevProps.name === nextProps.name; } function App(props) { console.log('%c render App', 'color: Yellow; font-weight: bold;'); const [count, setCount] = React.useState(0); const nameArr = []; return ( <> <button onClick={() => setCount((c) => c + 1)}>{count}</button> <br /> <br /> <Greeting name={nameArr} /> </> ); } ReactDOM.render(<App />, document.getElementById("root")); </script> </body>
memois used when the state changes in the parent component but that child component doesn't depend on it. In your case, it seems that the passedmemoizedCallbackdependency changes every time the internal state inGreeting(when you type in the input field) changes, and thus thepropstoInputBoxchanges every time you type. That's why it doesn't work.memoizedCallbackthat changes on every input change. Also, why do you want to avoid it? Re-rendering in you case is not that important/expensive.memoanduseCallbackto not re-render/call the child component/function is to not update the props/dependency array passed tomemo/useCallback. Once you understand this, implementing it is supposed to be straightforward.