Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/413.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript useState、UseRef或useMemo,我应该选择什么_Javascript_Reactjs_React Hooks_Memoization - Fatal编程技术网

Javascript useState、UseRef或useMemo,我应该选择什么

Javascript useState、UseRef或useMemo,我应该选择什么,javascript,reactjs,react-hooks,memoization,Javascript,Reactjs,React Hooks,Memoization,我有一个场景,需要在整个组件生命周期中存储函数的输出(该值永远不会更改) 考虑下面的例子 const UniqueIdView = () => { const [uniqueIdState1] = useState(() => uniqueId('prefix_')) const [uniqueIdState2] = useState(uniqueId('prefix_')) const uniqueIdRef = useRef(uniqueId('prefi

我有一个场景,需要在整个组件生命周期中存储函数的输出(该值永远不会更改)

考虑下面的例子

const UniqueIdView = () => {
    const [uniqueIdState1] = useState(() => uniqueId('prefix_'))
    const [uniqueIdState2] = useState(uniqueId('prefix_'))
    const uniqueIdRef = useRef(uniqueId('prefix_'))
    const uniqueIdMemo = useMemo(() => uniqueId('prefix_'), [])
    return (
        <div>
            {uniqueIdState1}
            {uniqueIdState2}
            {uniqueIdRef.current}
            {uniqueIdMemo}
       </div>
    )
}

因此,无论UniqueId重新呈现多少次,该值都不应更改。

传递给
useRef
的值只是初始值,但如果是函数调用,则每次呈现时都会调用该值。对你的问题的其余部分不太确定。每个挂钩都有特定的用途。挑一个适合你需要的

我有一个场景需要存储函数的输出 在整个组件生命周期中

对我来说,明确的选择是
usemo
hook来记忆一个可能代价高昂的函数调用的结果值

它没有定期更新,因此
useState
不适合。如果您决定将其存储在状态中,并且曾经需要对其进行更新,则需要一个带有依赖项的
useffect
hook,重新计算一个新值并调用状态更新程序函数。这本质上就是
usemo
hook

如果您决定将其存储在React ref中,那么您需要再次将其与
useffect
和一个依赖项配对,以更新
ref.current
值以保持其更新,而这实际上又为您提供了
useMemo
钩子

使现代化 由于您确实希望优化一个自定义钩子,该钩子为组件的生命周期提供一个静态唯一id:

  • 使用
    usemo

    const useUniqueId = (prefix = 'prefix_') => {
      return useMemo(() => uniqueId(prefix), []);
    };
    
  • 使用
    useState

    const useUniqueId = (prefix = 'prefix_') => {
      const [uniqueId] = useState(() => uniqueId(prefix));
      return uniqueId;
    };
    

  • 传递给
    useRef
    的值只是初始值,但如果是函数调用,则每次渲染都会调用该值。对你的问题的其余部分不太确定。每个挂钩都有特定的用途。挑一个适合你需要的

    我有一个场景需要存储函数的输出 在整个组件生命周期中

    对我来说,明确的选择是
    usemo
    hook来记忆一个可能代价高昂的函数调用的结果值

    它没有定期更新,因此
    useState
    不适合。如果您决定将其存储在状态中,并且曾经需要对其进行更新,则需要一个带有依赖项的
    useffect
    hook,重新计算一个新值并调用状态更新程序函数。这本质上就是
    usemo
    hook

    如果您决定将其存储在React ref中,那么您需要再次将其与
    useffect
    和一个依赖项配对,以更新
    ref.current
    值以保持其更新,而这实际上又为您提供了
    useMemo
    钩子

    使现代化 由于您确实希望优化一个自定义钩子,该钩子为组件的生命周期提供一个静态唯一id:

  • 使用
    usemo

    const useUniqueId = (prefix = 'prefix_') => {
      return useMemo(() => uniqueId(prefix), []);
    };
    
  • 使用
    useState

    const useUniqueId = (prefix = 'prefix_') => {
      const [uniqueId] = useState(() => uniqueId(prefix));
      return uniqueId;
    };
    

  • 首先简单回答:如果我必须决定使用哪种机制,我会选择
    usemo

    const uniqueId = useMemo(() => getUniqueId('prefix_'), []);
    
    它实现了我们在这里想要的所有功能:
    getId
    函数只被调用一次,因为依赖项数组是空的,返回值是稳定的,而且经济高效。没有与
    usemo
    相关的神奇成本,计算是重还是轻都无关紧要。正如Drew所说,它很简洁。 自定义挂钩如下所示:

    export const useUniqueId = () => {
      const uniqueId = useMemo(() => getUniqueId('prefix_'), []);
      return uniqueId;
    }
    
    较长的答案是: 通常,如果您希望一个值不以任何方式连接到渲染周期,并且在组件的生命周期内保持稳定,我会选择
    useRef
    。 但是
    useRef
    useState
    usemo
    一样不支持初始值设定项函数。我不想在每次渲染时调用
    getUniqueID
    ,因此会被迫将其与
    useffect
    组合以初始化ref。这在这里确实有点麻烦,所以我认为
    usemo
    在这里起作用

    const uniqueId = useRef();
    useEffect(() => { uniqueId.current = getUniqueId('prefix_') }, []);
    

    请注意,具有useEffect的解决方案仅在渲染函数运行到完成后提供值,如果您需要立即使用uniqueID,例如在某些元素上设置HTML属性ID,这将导致麻烦。

    首先简单回答:如果我必须决定使用哪种机制,我会选择
    useMemo

    const uniqueId = useMemo(() => getUniqueId('prefix_'), []);
    
    它实现了我们在这里想要的所有功能:
    getId
    函数只被调用一次,因为依赖项数组是空的,返回值是稳定的,而且经济高效。没有与
    usemo
    相关的神奇成本,计算是重还是轻都无关紧要。正如Drew所说,它很简洁。 自定义挂钩如下所示:

    export const useUniqueId = () => {
      const uniqueId = useMemo(() => getUniqueId('prefix_'), []);
      return uniqueId;
    }
    
    较长的答案是: 通常,如果您希望一个值不以任何方式连接到渲染周期,并且在组件的生命周期内保持稳定,我会选择
    useRef
    。 但是
    useRef
    useState
    usemo
    一样不支持初始值设定项函数。我不想在每次渲染时调用
    getUniqueID
    ,因此会被迫将其与
    useffect
    组合以初始化ref。这在这里确实有点麻烦,所以我认为
    usemo
    在这里起作用

    const uniqueId = useRef();
    useEffect(() => { uniqueId.current = getUniqueId('prefix_') }, []);
    

    请注意,具有useEffect的解决方案仅在渲染函数运行完成后提供值,如果您需要立即使用uniqueID(例如,在某些元素上设置HTML属性ID),这将导致问题。

    回答很好-一如既往-但我有一个但是…
    传递给useRef的值只是初始值,因此,如果是函数调用,则只能调用一次。
    关于这句话,您的回答不正确。如果我将一个函数传递给
    useRef
    ,该函数将永远不会被调用,而只是作为函数的引用存储。如果我将函数调用的结果传递给
    useRef