为什么let transporter = nodemailer.createTransport({
service: 'gmail',
port: 465,
secure: true,
auth: {
user: 'myemail@gmail.com',
pass: 'mypass'
}
});
钩子返回的对象存储应该保存在useRef
属性中的任何值?我们为什么不能直接将一些东西分配给ref对象,如下所示:
current
const sampleRef = useRef([]);
/** why can't we do this... */
sampleRef.push('1');
/** ...instead of this? Why an extra `current` object? */
sampleRef.current.pus('1');
返回包装在具有useRef
属性的另一个对象中的参数的目的是什么?
答案 0 :(得分:1)
据我了解,他们之所以这么做,是因为他们需要创建一个对象来密封 DOM元素对象(在开发模式下)并记忆。如您所知,如果我们要记住一些东西,我们需要将其转换为对象或数组。
参考:
RA_Min_1
https://github.com/facebook/react/blob/master/packages/react-reconciler/src/ReactFiberHooks.js#L916
答案 1 :(得分:1)
react hooks系统使用不可变的值。无论何时呈现组件,都会调用该挂钩(例如useState
挂钩),并且它们会生成一个或两个值(状态和设置函数)。如果此值与以前的值有所不同,则可能会调用其他钩子(初始化setter函数时{useEffect
)。
但是,有时我们不想对这些更改做出反应。只要价值存在,我们就不会在乎什么,我们也不会在乎是否有所改变。对于这种情况,我们有ref:
“ ref”对象是一个通用容器,其当前属性为 可变并且可以保存任何值,类似于 课。
无论何时需要存储值,都将使用该值,但不会导致重新渲染,也不会导致useMemo
,useCallback
,useEffect
等。要重新计算,您可以通过引用设置该值。由于ref本身将用作挂钩依赖项(useMemo(() => {}, [ref]
)的一部分,因此您无法对其进行更新。为了实现不变性,ref
对象内部的属性可以更改ref.current
,而无需重新计算依赖项,因为它是相同的引用。
答案 2 :(得分:1)
这个问题的答案并不特定于React及其钩子系统。 更改对象只是解决如何在不同的闭包/范围之间共享值的解决方案。
当您为组件调用useRef()
时,在React内部会创建一个“ ref对象”,并绑定到该组件的特定实例。
每次跨多个渲染调用useRef()
时,都会返回相同的“ ref object”。在其上设置current
是您存储值以在下一次渲染时重新访问它的方式。
通过类似的操作
let value = useRef();
value = 1234;
您将丢弃ref对象,并在本地范围内将其替换为新值。 React不可能跟踪该动作并更新存储在其内部的ref对象。 (实际上,React始终不会跟踪“引用对象”的任何动作,它只是将它们提供给您。您对它们进行突变,然后进行访问)。
但是使用当前的API,您可以
const ref = useRef(); // ref is an object that is stored somewhere in React internals
ref.current = 1234; // you update the property of that object
下次渲染组件时,React为您提供相同的ref对象,以便您可以使用之前设置的值。
答案 3 :(得分:0)
我正在尝试回答您问题的根本原因,我将其解释为:“似乎我们不需要具有.current属性的中间对象。”没错我们没有。无论关于useRef
的实际原因是什么,我都注意到有可能改为执行以下操作,该操作具有您在问题中所要求的语法(消除了.current
): / p>
//note foo is in array brackets by itself
const [foo /*no setFoo here*/]= useState({bar:"baz"});
...
foo.bar="hello"
或
//note foo in brackets by itself
const [foo /*no setFoo here*/]= useState([]);
...
foo.push(1);
这使我们可以直接更改foo
的属性,而无需使用.current
。只要我们从不调用setFoo
,对foo
的属性进行更改就不会导致自身的重新渲染。 foo
本身的值永远不会更改,因为它始终指向同一对象或数组。
但是,如果像useRef
这样的已更改属性出现在重新渲染之后,则与其他变量(包括useEffect
一样,有可能导致foo.bar
钩子在重新渲染后重新运行)。 useEffect
的第二个参数数组。
我还没有尝试let [foo]= useState("whatever")
。在这种情况下,我们将更改foo
的实际值,并依靠React在以后的重新渲染时将更改后的值返回给我们,即使我们从未通知过该更改。似乎很粗略。