今天使用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可以用来。
存储可变的数据
记事本
但这些文档相互矛盾,造成了许多错误和开发团队的冲突。
文档说了两件不同的事情,这是个问题。
那么,在这样的情况下,什么是 "正确 "的事情?
const MyComponent = (props) => {
const [myMap1, _] = useState(new Map()); // 1.
const myMap2 = useMemo(()=> new Map(), []); // 2.
const myMap3 = useRef(new Map()); // 3.
...
};
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
甚至是... 替换 useRef
由 useState
:const [ref] = useState({current:null});
ref.current = "hello";
缺点:我们又回到了旧的jQuery时代:-)。操作必须被强制设置,这意味着更多的手工工作和可能的错误。不可变的值操作也比突变更可预测(包括其他好处)。这就是为什么React中几乎所有的东西都是不可变的。
相反,在可能的情况下,保持声明性(React习语),并针对其特定情况使用预期的、优化的工具是有意义的。
useState
对于不可变的值,以声明的方式, 触发重新渲染。useMemo
用于成本价值的声明式记忆。源于 国体和道具useRef
对于 可变 值或DOM节点--独立于渲染闭合范围,无需使用 deps
,不触发重新渲染,更多的是手动的必要工作。钩子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很有用(当把道具作为对象传递,或者把一个备忘对象传递给传递给上下文提供者的值道具时很有用)。