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

IT技术 javascript reactjs react-native react-navigation react-navigation-v5
2021-05-19 13:19:32

useFocusEffect当我聚焦视图时,我试图在我的视图中重新渲染一个组件。

我做了:

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

然后:

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

和 jsx:

<SwipeListView key={theKey} /> 

它不能很好地工作,我有错误: Maximum update depth exceeded

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

我的react-router没有这个问题。

2个回答

问题在这里:

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

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

有2种解决方案:

删除Key依赖项:

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