焦点发生时如何在反应导航中重新渲染组件?

How to rerender a component in react-navigation when focus happen?

我正在尝试 useFocusEffect 在聚焦视图时重新呈现视图中的组件。

我做到了:

const [theKey, setTheKey] = useState(0);

然后:

useFocusEffect(() => { setTheKey(theKey + 1) }, [theKey]);

和 jsx:

<SwipeListView key={theKey} /> 

效果不佳,出现错误:Maximum update depth exceeded

有人可以分享重新渲染的方法吗?

我没有反应路由器的这个问题。

问题在这里:

useFocusEffect(() => { setTheKey(theKey + 1) }, [theKey]);

在此函数中更新 theKey。每次 theKey 更新时,都会再次调用效果。这会导致无限循环。

有2种解决方案:

删除密钥依赖项:

useFocusEffect(
    () => { setTheKey(theKey + 1) }, 
    ["replace with something else"]
);

更新状态前添加条件:

useFocusEffect(
    () => { if ("some condition") setTheKey(theKey + 1) }, 
    [theKey]
);

这将防止无限循环。

我也遇到了 useFocusEffect 的问题。它要么触发无限循环/渲染,要么保留该函数的陈旧版本。

const [count, setCount] = useState(1);
const doSomething = useCallback(() => {
    console.log(count);
    setCount(count + 1);
}, [count]);

useFocusEffect(
    useCallback(() => {
        doSomething(); // Count will always be 1 (cached value)
    }, [doSomething])
);

useFocusEffect(
    useCallback(() => {
        doSomething(); // Latest count, but infinite loop due to doSomething() is recreated when count changes
    }, [doSomething])
);

相反,可以尝试结合使用 useIsFocus 和 usePrevious,这与现有的 useEffect 方法配合得很好。

import { useIsFocused } from "@react-navigation/native";
import { useEffect, useRef } from "react";

// usePrevious custom hook
function usePrevious(value) {
    const ref = useRef();
    useEffect(() => {
        ref.current = value;
    });
    return ref.current;
}

const isFocused = useIsFocused();
const prevIsFocused = usePrevious(isFocused);


useEffect(() => {
    if (!prevIsFocused && isFocused) {
        // Run your code here
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocused]);