使用 api 调用在 useEffect 中未发生状态更新

state update not happening in useEffect with api call

我是 React.js 的新手。我想根据其他一些 state.I 调用 api 来获取新选项来更新我的表单中的选项。所以这个 api 需要在状态发生变化时被调用。

const [selectedNamespace,setselectedNamespace] = useState[default];

每当 selectedNamespace 发生变化时,我需要调用 fetchData api。

 const fetchItemData = useCallback(() => {
        setError(null);
        setSuccessMessage(null);
        fetch(getApiPath + selectedNamespace)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Something went wrong while fetching item data');
                }
                return response.json();
            }).then(data => {
                setItemData(data);
            }).catch(error => {
                setError(error.message);
            })
    }, []);

这是我用来调用它的 useEffect 函数:

 useEffect(() => {
        if (!isEmptyString(selectedNamespace))
            fetchItemData();
    }, [selectedNamespace, fetchItemData])

我面临的问题是我在 fetchItemdData 中访问的 selectedNamespace 参数始终为空。我认为状态更新正在延迟,因为我无法获得 selectedNamespace。我是 useEffect 和 useCallback 挂钩的新手。有人可以让我知道我的错误和处理这个问题的正确方法吗?

我很确定,您不需要将 fetchItemdData 包装在 useCallback 中。

The problem that I'm facing is that the selectedNamespace parameter that I'm accessing in my fetchItemdData is always empty.

const fetchItemData = useCallback(() => {
   ...
, []); // <--- empty dependency. This is why selectedNamespace always empty

useCallback 是我们需要记忆回调时使用的钩子。 (您可以从以下 link https://en.wikipedia.org/wiki/Memoization 中阅读有关记忆的内容)

因此,useCallback 将 return 记忆化的回调版本,仅当其中一个依赖项已更改时才会更改。这在将回调传递给依赖于引用相等性的优化子组件以防止不必要的渲染时很有用。它的工作方式类似于 shouldComponentUpdate 生命周期钩子。

这就是useCallback的小注意事项。 在上面的示例中,您已经分享了当您需要在每次某个值的值更改时更新状态时,不需要使用Callback。

const [selectedNamespace,setselectedNamespace] = useState[default];

useEffect(() => {
        if (!isEmptyString(selectedNamespace))
            fetchItemData();
    }, [selectedNamespace, fetchItemData])

function fetchItemData(){
//Whatever data you want
}

function onSetValueOfNamespace(){
setselectedNamespace("abcd");
}

因此,无论何时设置命名空间的值,都会调用 useEffect。此外,只要您安装此特定组件,useEffect 就会在开始时被调用一次。 希望这个回答对您有所帮助