首页 > 解决方案 > React useMemo:如何全局缓存对象(不是每个钩子使用)

问题描述

我正在创建一个自定义 CSS 钩子。
它包含用于生成 css 的昂贵计算,因此需要对其进行缓存。
钩子被多个组件共享。无论有多少组件使用它,
我都需要生成器执行一次。

我尝试使用useMemo,但它为每个钩子使用缓存。
如果useWhateverStyleSheed()使用 3 次,则生成器也会生成 3 次。
这不是故意的。我希望发电机运行一次。

这里的虚拟钩子:
useStyleSheetCompiler是基本钩子。
useFooStyleSheetuseAwesomeStyleSheet实现。

查看此沙箱或查看以下代码:

import {
    default as React,
    useMemo,
    useCallback,
}                           from 'react'


type StyleSheet = {[key: string]: string }
type SSFactory = () => StyleSheet

const useStyleSheetCompiler = (factory: SSFactory): StyleSheet => {
    const cache = useMemo(() => {
        return factory();
    }, [factory]);

    return cache;
}

const useFooStyleSheet = (): StyleSheet => {
    return useStyleSheetCompiler(() => {
        console.log('generating foo-css once and cached');
        return {
            foo: 'whatever'
        }
    });
}

const useAwesomeStyleSheet = (): StyleSheet => {
    return useStyleSheetCompiler(useCallback(() => {
        console.log('generating awesome-css once and cached');
        return {
            foo: 'whatever'
        }
    }, []));
}



const Component1 = () => {
    const fooCss = useFooStyleSheet();

    return <p className={fooCss.foo}>test</p>
}

const Component2 = () => {
    const awesomeCss = useAwesomeStyleSheet();

    return <p className={awesomeCss.foo}>test</p>
}

function App() {
    const styleSheet1 = useFooStyleSheet();
    const styleSheet2 = useFooStyleSheet();
    const styleSheet3 = useAwesomeStyleSheet();

    return (
        <div className="App">
            <Component1/>
            <Component2/>
            <div className={[
                    styleSheet1.foo,
                    styleSheet2.foo,
                    styleSheet3.foo,
                ].join(' ')}
            >
                hello
            </div>
        </div>
    );
}

export default App;

标签: reactjsreact-hooks

解决方案


推荐阅读