我应该使用Ref来存储一次性初始化数据吗?

问题描述 投票:0回答:1

今天使用react的ref可能会有点混乱,回到类组件的时代,在文档中是很清楚的。

我们应该使用refs主要用于 DOM元素 :

https:/reactjs.orgdocsrefs-and-the-dom.html。

但今天我们有钩子与功能组件.而且我们使用的是 useRef 钩。

同时,这也给我们带来了新的模式。 用ref来包含 回调或任何 资料 我们想保留(一种状态),但不需要重新渲染.它是一个强大的API,也显示在文档中。

https:/reactjs.orgdocshooks-faq.html#is-therae-something-like-instance-variables。

所以现在ref可以用来。

  1. 存储可变的数据

  2. 记事本

但这些文档相互矛盾,造成了许多错误和开发团队的冲突。

文档说了两件不同的事情,这是个问题。

那么,在这样的情况下,什么是 "正确 "的事情?


const MyComponent = (props) => {
   const [myMap1, _] = useState(new Map());    // 1.
   const myMap2 = useMemo(()=> new Map(), []); // 2.
   const myMap3 = useRef(new Map());           // 3.

   ...
};

javascript reactjs react-hooks memoization
1个回答
1
投票

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
甚至是... 替换 useRefuseState:
const [ref] = useState({current:null});
ref.current = "hello";

缺点:我们又回到了旧的jQuery时代:-)。操作必须被强制设置,这意味着更多的手工工作和可能的错误。不可变的值操作也比突变更可预测(包括其他好处)。这就是为什么React中几乎所有的东西都是不可变的。

相反,在可能的情况下,保持声明性(React习语),并针对其特定情况使用预期的、优化的工具是有意义的。

  • useState 对于不可变的值,以声明的方式, 触发重新渲染。
  • useMemo 用于成本价值的声明式记忆。源于 国体和道具
  • useRef 对于 可变 值或DOM节点--独立于渲染闭合范围,无需使用 deps,不触发重新渲染,更多的是手动的必要工作。

0
投票

钩子useRef可以用来存储任何值,例如,你有一个对象、一个数组或一个地图,你不想为每一次重新初始化,你可以使用Ref钩子。

 // this code will recreate the object in memory on each rerender
 const myObj = {foo: 'foo', bar: 'bar'}

 // here you have the same object in memory even after rerenders
 const refObj = useRef({foo: 'foo', bar: 'bar'})

同样,useState钩子也可以用来存储普通的状态变量。

当一些值依赖于你的代码中的另一个变量,并且你想只在变量改变时才改变该值时,useMemo很有用(当把道具作为对象传递,或者把一个备忘对象传递给传递给上下文提供者的值道具时很有用)。

© www.soinside.com 2019 - 2024. All rights reserved.