Home > Software engineering >  How to avoid a function to be called twice when the state changes?
How to avoid a function to be called twice when the state changes?

Time:02-05

I have this react component

const [filter, setFilter] = useState(valueFromProps);
const [value, setValue] = useState(valueFromProps);

const initialRender = useRef(true);
useEffect(() => {
  if (initialRender.current) {
    initialRender.current = false;
  } else {
    console.log("set new value");
    const newValue = calculateNewValue(filter);
    setvalue(() => newValue);
  }
}, [filter]);

const getReports = (value) => {
  console.log(value);
  //generate some html
};

return (
  <>
    <div>
      {getReports(value)}
    </div>
  </>
);

pretty standard. It works as expected, the only problem is that getReports is executed twice every time the state filter changes. The first time with the old value and the second time with the new value.

I put some console.log and I can see the function is called twice despite the log in useEffect is printed only once.

What can I do to make it run only once please?

CodePudding user response:

not sure but maybe because of setvalue(() => newValue);, the callback here is used to make updates after the state is changed so setFilter ran and after that setvalue(() => newValue) <-- this

try: setvalue(calculateNewValue(filter));

CodePudding user response:

React runs return statement after filter state update and only then runs useEffect, which itself updates state and triggers re-render.

I would suggest update your state in same place you update your filter or use useMemo for value if it only depends on filter state.

const [filter, setFilter] = useState(valueFromProps);
const [value, setValue] = useState(valueFromProps);

const getReports = (value) => {
  console.log(value);
  //generate some html
};

cons updateFilter = (filter) => {
  setFilter(filter);
  setValue(calculateNewValue(filter);
}

return (
  <>
    <div>
      {getReports(value)}
    </div>
  </>
);
  • Related