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