反应钩子避免重新渲染并保持必要的深度

时间:2020-04-18 13:33:38

标签: reactjs react-hooks

我错过了useEffect,useCallback和deps的东西。

我有一个背景和一个组成部分。我的组件使用fetch()加载我需要的每个数据,并在上下文中将布尔值设置为true以显示微调框。我在需要时在另一个组件中使用上下文。

const LoadingApp = ({children}) => {
    const loadingContext = useContext(LoadingContext);

    const fetchMyData = useCallback(() => {
        loadingContext.setLoading(true);
    }, [loadingContext]);


    useEffect(() => {
        fetchMyData();
    }, [fetchMyData]);

    return (
        <React.Fragment>
            {children}
        </React.Fragment>
    );
};


const LoadingProvider = ({children}) => {
    const [loading, setLoading] = useState(false);

    const setLoading = useCallback((isLoading) => {
        setLoading(loading + (isLoading ? 1: -1));
    }, [setLoading, loading]);

    const isLoading = useCallback(() => {
        return loading > 0;
    }, [loading]);

    return (
        <LoadingContext.Provider value={{setLoading, isLoading}}>
            {children}
        </LoadingContext.Provider>
    )
}

我知道我可以从useEffect或useCallback中删除dep,但这似乎是解决我问题的错误方法,因为dep是必需的。

如何在useEffect或useCallback的上下文中调用函数而不重新渲染所有内容?

2 个答案:

答案 0 :(得分:0)

如果您正在呼叫setLoading,那么您总是会触发您想要的重新渲染。

您可能有一个空的deps,这意味着效果只会运行一次。

答案 1 :(得分:0)

loading值更改时,上下文始终更改。将useEffect的依赖项更改为仅依赖于{{1}不变的setLoading,并且将保持不变。useCallback是基于useState的。 >

const { setLoading } = useContext(LoadingContext);

const fetchMyData = useCallback(() => {
  setLoading(true);
}, [setLoading]);

您实际上不需要useCallback,因为它执行的操作与原始setLoading相同。您可以安全地删除此内容:

const setLoading = useCallback((isLoading) => {
  setLoading(isLoading);
}, [loading]);