Ref*_*Man 11 javascript memoization reactjs react-hooks
今天使用 React 的 ref 可能有点令人困惑。回到类组件的时代,文档中已经非常清楚了。
我们应该主要对DOM 元素使用 refs :
https://reactjs.org/docs/refs-and-the-dom.html
但今天我们把钩子和功能组件结合在一起。我们正在使用useRef钩子。
此外,这也给我们带来了新的模式。使用 ref 包含回调,或任何我们想要保留的数据(某种状态),但不需要重新渲染。它是一个强大的 API,也出现在文档中:
https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables
所以现在 ref 可用于:
存储可变数据
记忆化的种类
但这些文档相互矛盾。并导致许多错误和开发团队的冲突。
医生说了两件事,这是一个问题。
那么,在这种情况下,“正确”的做法是什么?
const MyComponent = (props) => {
const [myMap1, _] = useState(new Map()); // 1.
const myMap2 = useMemo(()=> new Map(), []); // 2.
const myMap3 = useRef(new Map()); // 3.
...
};
Run Code Online (Sandbox Code Playgroud)
useMemo是一种声明性的 性能优化技术。
声明性,因为它依赖于属于特定渲染的周围范围的状态或道具依赖性,并自动(重新)创建记忆值。我们不必告诉我们useMemo这样做。
useRef是任何值的可变存储框,例如独立于当前渲染范围的值更新。
useRef没有任何依赖关系,因此不会自动更改任何值。您必须通过编写手动完成此操作ref.current = ...(DOM 节点是一个例外)。这就是为什么你可以将其视为进入命令式useRef世界的逃生口。
// instead of
const val = useMemo(() => 42, [myDep]); // 42 stands for some complex calculation
// do this
const ref = useRef();
ref.current = 42 // assign 42 imperatively to ref somewhere in render
Run Code Online (Sandbox Code Playgroud)
或者甚至替换 useRef为useState:
const [ref] = useState({current:null});
ref.current = "hello";
Run Code Online (Sandbox Code Playgroud)
缺点:我们又回到了旧的 jQuery 时代:-)。操作必须强制设置,这意味着更多的手动工作和可能的错误。不可变的价值操纵也比突变更可预测(包括其他好处)。这就是为什么 React 中几乎所有内容都是不可变的。
相反,在可能的情况下保持声明性(React 惯用)并针对特定情况使用预期的优化工具是有意义的:
useState对于以声明方式不可变的值,触发重新渲染useMemo用于从状态和道具中导出的昂贵值的声明性记忆useRef对于可变值或 DOM 节点 - 独立于渲染闭包范围,不需要deps,不会触发重新渲染,更多手动命令式工作| 归档时间: |
|
| 查看次数: |
9048 次 |
| 最近记录: |