Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React - functional components keep re-render when passing functions as props

i have an issue in my react app and i dont know how to solve it;

i have an array with values and chosen list and a function to add item to the chosen list

import React, { useState } from "react";
import Parent from "./Parent";
export default function App() {
  const [chosenList, setChosenList] = useState([]);
  const array = ["dsadas", "dasdas", "dasdasd"];

  const addToChosenList = string => {
    setChosenList([...chosenList, string]);
  };

  return (
    <div className="App">
      <Parent
        arr={array}
        chosenList={chosenList}
        addToChosenList={addToChosenList}
      />
    </div>
  );
}

Parent component that mapping through the array and give the Nested component the props: item, addToChosenList, inList

import React from "react";
import Nested from "./Nested.js";

export default function Parent({ arr, addToChosenList, chosenList }) {
  return (
    <div className="App">
      {arr.map((item, index) => (
        <Nested
          key={index}
          item={item}
          addToChosenList={addToChosenList}
          inList={chosenList.findIndex(listitem => listitem === item) > -1}
        />
      ))}
    </div>
  );
}

Nested component that displays the item and giving it the addToChosenList function to add the item to the chosen list

import React, { memo } from "react";
export default memo(function Parent({ item, addToChosenList, inList }) {
  const childFunctionToAddToChosenList = () => {
    addToChosenList(item);
  };
  return (
    <div className="App" onClick={childFunctionToAddToChosenList}>
      <div>{item}</div>
      {inList && <div>in List</div>}
    </div>
  );
});

every Nested component keeps re-render after i clicked only one item in the list i believe it renders because of the function addToChosenList that changes when i change the state

anyone knows how to solve it ??

thanks :)

like image 525
Harel Avatar asked Oct 20 '25 01:10

Harel


1 Answers

addToChosenList will point to a new reference on every re-render, wrap it in useCallback which will keep the same reference across re-renders unless one of the variables inside of the dependencies array has changed, if we pass an empty array the function will keep the same reference across the entire component lifecycle.

you will also need to use a functional update to avoid stale state due to the closure

const addToChosenList = useCallback(string => {
  setChosenList(prevState => [...prevState, string]);
}, []);
like image 185
Asaf Aviv Avatar answered Oct 21 '25 15:10

Asaf Aviv



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!