javascript 如何避免函数在状态改变时被调用两次?

von4xj4u  于 2023-02-07  发布在  Java
关注(0)|答案(3)|浏览(121)

我有这个React成分

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>
  </>
);

非常标准。它按预期工作,唯一的问题是每次状态filter更改时,getReports执行两次。第一次使用旧值,第二次使用新值。
我放了一些console.log,我可以看到这个函数被调用了两次,尽管useEffect中的日志只打印了一次。
我怎样才能让它只运行一次呢?

uz75evzq

uz75evzq1#

不确定,但可能是因为setvalue(() => newValue);,此处的回调用于在状态更改后进行更新,因此setFilter运行,之后setvalue(() => newValue)〈-- this
尝试:setvalue(calculateNewValue(filter));

py49o6xq

py49o6xq2#

React在过滤器状态更新后运行return语句,然后才运行useEffect,useEffect本身更新状态并触发重新呈现。
我建议在更新过滤器的同一个地方更新状态,或者如果它只依赖于过滤器状态,使用useMemo作为值。

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>
  </>
);
rm5edbpk

rm5edbpk3#

尽管@Andyally提出的解决方案不起作用,但由于他的建议,我使用useMemo提出了一个解决方案

let value = props.value;
const [filter, setFilter] = useState(valueFromProps);

value = useMemo(() => calculateNewValue(filter), [filter]);

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

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

相关问题