reactjs React钩:如何只示例化示例变量一次

krugob8w  于 2022-12-18  发布在  React
关注(0)|答案(3)|浏览(134)

我想使用react钩子从我的 prop 中获得值。
我想计算这个值只有一次,而不是在每一个渲染。
这是我想到的第一个解决方案,但如果 prop 改变,z不会重新计算。

function App(props: { x: number; y: number }) {
    
    const zRef = useRef<number | undefined>(undefined);

    if( zRef.current === undefined ){
    
        //Let's assume the computation of x + y is costly, I 
        //want to avoid doing it every render.
        zRef.current = props.x + props.y;
    
    }

    return (<span>{zRef.current}</span>);

}

我发现的第二种方法是:

function App(props: { x: number; y: number }) {
    
    const zRef = useRef<number | undefined>(undefined);

    useEffect(()=>{

        zRef.current = props.x + props.y;

    },[props.x, props.y]);

    return (<span>{zRef.current}</span>);

}

但问题是zRef.current在第一次渲染时是undefined
对这件事有任何意见都很感激。

kxkpmulp

kxkpmulp1#

你试过useMemo吗?
useMemo似乎适合您的用例,因为它只允许您在dependency数组中指定的任何一个值发生更改时重新计算值。
就像这样:

const z = useMemo(() => {
    return props.x + props.y
}, [props.x, props.y])
von4xj4u

von4xj4u2#

如果你只是想提高性能,你可以使用useMemo,就像在另一个答案中描述的那样!如果你真的依赖于只计算一次这个值,听起来好像它会起作用,但是仔细阅读文档:

您可以依赖useMemo作为性能优化,而不是作为语义保证。

在未来,React可能会选择“忘记”一些先前记忆的值,并在下次渲染时重新计算它们,例如为屏幕外组件释放内存。编写代码时,即使没有useMemo也能正常工作,然后添加它以优化性能。
因此,解决问题的一种方法是手动比较输入是否发生了变化,然后重新计算值:

// https://reactjs.org/docs/hooks-faq.html
function usePrevious(value) {
  const ref = useRef();
  useEffect(() => { ref.current = value; });
  return ref.current;
}

function App(props: { x: number; y: number }) {
    const zRef = useRef<number>(0);
    const prevProps = usePrevious(props);
    if (!prevProps || prevProps.x !== props.x || prevProps.y !== props.y){
        zRef.current = props.x + props.y;
    }
    return (<span>{zRef.current}</span>);
}

如果您经常需要这样的缓存值,您甚至可以使用这个技巧编写自己的cache-hook。

yrdbyhpb

yrdbyhpb3#

如果希望变量只被示例化一次,可以像这样使用useMemo钩子。

const z = useMemo(() => {
    return 20
}, [])

注意空数组;它将确保您的元素只被示例化一次。

相关问题