如何在第三方库中调用状态设置器时防止状态重置

How to prevent state from resetting when calling a state setter in a 3rd party library

提问人:John Taylor 提问时间:7/21/2023 最后编辑:Drew ReeseJohn Taylor 更新时间:7/22/2023 访问量:41

问:

我正在尝试将 React 类组件转换为 React 函数组件。

有一个函数既可以在组件内部调用,也可以从组件外部调用。 调用函数组件函数时,钩子采用初始值。当我使用旧的类组件方式时,一切正常。为什么会这样,如何解决这个问题?onChangeuseState

const MyInput = (props) => {
  const { someLib, ...otherProps } = props;
  const [test, setTest] = useState(1); // console show 1,2,3, etc
            
  useEffect(() => {
    someLib && someLib.addCallback(onChange);
  }, []);

  const onChange = (event) => { 
    setTest(test + 1) // this function can called inside MyInput, and from someLib, 
                      // when it called from someLib, 'test' is reset, but in class component everything good 
  }
}
JavaScript ReactJS 闭包

评论


答:

1赞 Zachiah 7/21/2023 #1

问题是这是一个陈旧的闭包。你需要做的是使看起来像这样:onChangeonChange

const onChange = (event) => {
    setTest(oldTest => oldTest +1)
}

或者,您可以添加到依赖项数组中,确保进行清理。(无论如何你都应该这样做,但现在它更重要)testuseEffect

useEffect(() => {
    someLib && someLib.addCallback(onChange);

    return () => {
        someLib.removeCallback(onChange);
    }
}, [someLib, test]);

从技术上讲,如果您正在执行后一种方法,则需要useCallback

const onChange = useCallback((event) => {
    setTest(test + 1);
}, [test]);

useEffect(() => {
    someLib && someLib.addCallback(onChange);

    return () => {
        someLib.removeCallback(onChange);
    }
}, [someLib, onChange]);

这样做的好处是,您不必跟踪 In Different Place的依赖项。的依赖项列表现已关闭。onChangeonChange

评论

1赞 Ori Drori 7/22/2023
使用(条件链接)对回调进行添加和删除。someLib?.