gpt4 book ai didi

reactjs - 在react hooks中生成新的组件类型,如何保持性能?

转载 作者:行者123 更新时间:2023-12-05 07:09:08 25 4
gpt4 key购买 nike

我正在探索一个钩子(Hook),它可以生成一个包装器组件,以减少将动画添加到我的 native react 应用程序的样板文件。我已经写了一个钩子(Hook),它返回动画值并负责在内部管理它们,效果很好。然而,每次我使用它时,我都必须像这样编写应用动画值的样板:

//pseudocode
const [animatedValue, animationRef, ...otherUsefuLStuff] = useMyGenericAnimationHook(...some animation config)

return (
<Animated.View style={{transform: [{translateY: animatedValue}]}}>
.....
</Animated.View>
)

这没什么大不了的,但它仍然是我必须为每个动画添加的一些样板文件。我正在考虑是否可以从我的动画 Hook 返回一个包装器组件来抽象掉这个样板,如下所示

//pseudocode
const [AnimatedTranslateY, animatedValue, animationRef, ...otherUsefulStuff] = useMyGenericAnimationHook(... some animation config)

return (
<AnimatedTranslateY>.....</AnimatedTranslateY>
)

这看起来更干净,但是从钩子(Hook)返回一个新的组件类型肯定会导致问题。 React 将在每次渲染时拆除并重建子组件,因为每次 useMyAnimationHook() 运行时它都会返回一个新的组件类型!

我最初的想法是像这样在我的钩子(Hook)中记住返回的组件类型

//pseudocode
const useMyGenericAnimationHook= (....configuration arguments) => {
const animatedValueRef = ....create the animated value(s) ref(s)

const WrapperView: React.FC<ViewProps> = useMemo(
() =>
React.memo(({ children, style, ...restProps }) => (
<Animated.View {...restProps}
style={[style, { transform: ...apply animated value(s)}]}>
{children}
</Animated.View>
)),
[animatedValueRef.current]
)

return [WrapperView, animationHandle, otherUsefulStuff]
}

这是我有点困惑的地方。我认为这应该可以正常工作,而不是在每次渲染时重建树。组件类型应该保持稳定,除非给 useMemo 的依赖项发生变化,此时我们仍然希望它呈现。然而,我对此并不完全有信心。

使用 <WrapperView> 时 react 的行为是什么?

这不是一个好的模式有什么原因吗?

感谢您的任何见解!

最佳答案

还有一个想法。我将稍微调整一下你的 hook API,这样你就不会返回新的组件(只是将 props 添加到 Animated.View 组件),而是返回一组返回包装器 props 的函数。然后,调用所需的函数并将结果合并到组件的 style 属性中。示例:

function useMyGenericAnimationHook(...animationConfig) {
let animatedValue, animationRef, otherUsefulStuff;
return {
animatedValue,
animationRef,
...otherUsefulStuff,
// here's the meat of it
translateY: () => ({
transform: [{translateY: animatedValue}]
}),
color: () => ({
color: `hsl(120,100%,${animatedValue}%)`
}),
};
}

function Component() {
let { translateY, color } = useMyGenericAnimationHook(...animationConfig);
return (
<Animated.View style={{ ...translateY(), ...color() }}>
{children}
</Animated.View>
);
}

旧答案

我喜欢这个图案——它看起来很干净。只要您确保它不会在每次渲染时生成新的组件类型,它就应该是高性能的,并且 useMemo 应该适用于此。

另一种选择是将组件移到 Hook 之外。如果这适用于您的用例,它可以保证渲染之间的引用相等性。但是,它不允许您将 props 绑定(bind)到组件,因此用户必须提供任何所需的 props。

//pseudocode
const WrapperView = React.memo(({ children, style, ...restProps }: ViewProps) => (
<Animated.View {...restProps}
style={[style, { transform: ...apply animated value(s)}]}>
{children}
</Animated.View>
);

const useMyGenericAnimationHook= (....configuration arguments) => {
const animatedValueRef = ....create the animated value(s) ref(s)

return [WrapperView, animationHandle, otherUsefulStuff]
}

第三种但更笨拙的选择是从钩子(Hook)中返回 JSX。

function useDiv() {
return <div />;
}
function Component(props) {
const div = useDiv();
return (
<main>{div}</main> // equivalent to <main><div/></main>
)
}

您基本上可以将 JSX 复制粘贴到呈现的输出中,这可能适合您的用例。不过,如果前两个选项都不适合您,我只会使用它。

关于reactjs - 在react hooks中生成新的组件类型,如何保持性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61686097/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com