Javascript 我应该使用useRef存储一次性初始化数据吗?
今天使用react的ref可能有点混乱。 回到类组件时代,文档中的内容非常清楚 我们应该主要为DOM元素使用ref: 但今天我们有了挂钩和功能组件。 我们使用的是Javascript 我应该使用useRef存储一次性初始化数据吗?,javascript,reactjs,react-hooks,memoization,Javascript,Reactjs,React Hooks,Memoization,今天使用react的ref可能有点混乱。 回到类组件时代,文档中的内容非常清楚 我们应该主要为DOM元素使用ref: 但今天我们有了挂钩和功能组件。 我们使用的是useRefhook 同时,这也给我们带来了新的模式。使用ref包含回调,或任何数据,我们希望保留(某种状态),但无需重新提交。 它是一个功能强大的API,也显示在文档中: 因此,现在ref可用于: 存储可变数据 一种回忆录 但这些文件相互矛盾。并在开发团队中造成许多错误和冲突 医生说了两件不同的事情,这是个问题 那么,在这样的情况
useRef
hook
同时,这也给我们带来了新的模式。使用ref包含回调,或任何数据,我们希望保留(某种状态),但无需重新提交。
它是一个功能强大的API,也显示在文档中:
因此,现在ref可用于:
常量MyComponent=(道具)=>{
常量[myMap1,]=useState(new Map());//1。
const myMap2=useMemo(()=>new Map(),[]);//2。
const myMap3=useRef(new Map());//3。
...
};
钩子useRef可以用来存储任何值,例如,您有一个对象、一个数组或一个映射,您不想为每个重新渲染器重新初始化它
您可以使用userefhook
// 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非常有用(将道具作为对象传递或将已记忆的对象传递给传递给上下文提供程序的道具值时,useMemo非常有用)。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-idiomatic)并针对特定情况使用预期的优化工具是有意义的:
以声明方式对不可变值触发重新呈现useState
用于对从状态和道具派生的昂贵值进行声明性记忆useMemo
用于可变值或DOM节点-独立于渲染闭包范围,不需要useRef
,不会触发重新渲染,更需要手动操作deps
this
上下文来存储可变的实例值。对于函数组件,情况并非如此,因此我们需要一个类似于useRef
的钩子。不管是类还是函数:ref仍然是一个框,其中可以存储和修改任何值(DOM节点、计算等)。所以是的:ref得到了功能组件的额外用例。