将 const 值存储在变量中与存储在状态中有区别吗?
Is there a difference between storing a const value in a variable vs in state?
我注意到有几种方法可以在 React 功能组件中实现看似相同的功能。当您拥有本质上仅在该组件内部需要的配置值时(只是一个常量值,从未传入或修改)您可以只使用常规 const
或者您可以将其存储在组件的状态中。
标准变量:
function Example1() {
const a = 1
return <div>{ a }</div>
}
存储状态:
function Example2() {
const [a] = useState(1)
return <div>{ a }</div>
}
我的印象是,在幕后这会导致 Example1 在每个渲染器上创建一个变量然后处理它,而 Example2 将创建一次变量并维护它直到组件被卸载。那是准确的吗?就 performance/good 实践而言,这些方法中的一种更可取吗?
Is that accurate?
是的,正如您所说,Example1 在每个渲染器上创建一个变量(在范围末尾将其标记为 "disposable" - 与 React 无关,但 Javascript), Example2 创建变量一次并维护它直到组件被卸载(或者这个变量的状态通过 setState
改变)。
And is one of these methods preferable in terms of performance/good practice?
作为一个好的做法 - 示例 1。
至于性能,应该是Example1。 Example2 运行 useState
并将值 a
与每个渲染器的先前状态进行比较,这 "much more expensive" 比声明一个变量。
一个更好的例子是比较组件参考/memoized变量与变量(Example1):
function Example2() {
const a = useRef(1);
const b = useMemo(() => 1, []);
return <div>{a.current} , {b}</div>
}
但答案几乎相同。
看到这样的代码表明 ref a
可能会改变 。使用useMemo
表示b
是一个"heavy computation"变量,如果不是,那只是一个开销(同上解释),更好用示例 1.
您的假设几乎是正确的,useState
变量创建一次并在每次渲染时重复使用。
但是,主要区别在于修改使用 useState 创建的变量(通过其 setter 方法)会触发组件刷新。
如果您只需要在渲染之间保存一个值,您应该使用其他挂钩,例如useRef、useCallback 或 useMemo
将此答案的重点放在何时使用什么上。
基本概念,
- 如果您需要观察一个值并对其做出反应,将其存储在状态中是有意义的。
- 如果您只想存储一个值用于 display/calculation 目的,使用
const/let
更合适。
现在在你的第二个例子中
const [a] = useState(1)
这行代码完全错误。那是因为您正在添加观察者但不接受 setter 回调。
Example1 creating a variable on each render
是的,这是正确的。在 Example2 中,它创建了 1 个变量,但是 React 中的状态是不可变的。这意味着,每次渲染时,整个对象都会被复制到一个临时变量中,销毁并再次创建。由于这个事实,建议不要在状态中存储巨大的对象,因为它会对您的性能产生不利影响。
我注意到有几种方法可以在 React 功能组件中实现看似相同的功能。当您拥有本质上仅在该组件内部需要的配置值时(只是一个常量值,从未传入或修改)您可以只使用常规 const
或者您可以将其存储在组件的状态中。
标准变量:
function Example1() {
const a = 1
return <div>{ a }</div>
}
存储状态:
function Example2() {
const [a] = useState(1)
return <div>{ a }</div>
}
我的印象是,在幕后这会导致 Example1 在每个渲染器上创建一个变量然后处理它,而 Example2 将创建一次变量并维护它直到组件被卸载。那是准确的吗?就 performance/good 实践而言,这些方法中的一种更可取吗?
Is that accurate?
是的,正如您所说,Example1 在每个渲染器上创建一个变量(在范围末尾将其标记为 "disposable" - 与 React 无关,但 Javascript), Example2 创建变量一次并维护它直到组件被卸载(或者这个变量的状态通过 setState
改变)。
And is one of these methods preferable in terms of performance/good practice?
作为一个好的做法 - 示例 1。
至于性能,应该是Example1。 Example2 运行 useState
并将值 a
与每个渲染器的先前状态进行比较,这 "much more expensive" 比声明一个变量。
一个更好的例子是比较组件参考/memoized变量与变量(Example1):
function Example2() {
const a = useRef(1);
const b = useMemo(() => 1, []);
return <div>{a.current} , {b}</div>
}
但答案几乎相同。
看到这样的代码表明 ref a
可能会改变 。使用useMemo
表示b
是一个"heavy computation"变量,如果不是,那只是一个开销(同上解释),更好用示例 1.
您的假设几乎是正确的,useState
变量创建一次并在每次渲染时重复使用。
但是,主要区别在于修改使用 useState 创建的变量(通过其 setter 方法)会触发组件刷新。
如果您只需要在渲染之间保存一个值,您应该使用其他挂钩,例如useRef、useCallback 或 useMemo
将此答案的重点放在何时使用什么上。
基本概念,
- 如果您需要观察一个值并对其做出反应,将其存储在状态中是有意义的。
- 如果您只想存储一个值用于 display/calculation 目的,使用
const/let
更合适。
现在在你的第二个例子中
const [a] = useState(1)
这行代码完全错误。那是因为您正在添加观察者但不接受 setter 回调。
Example1 creating a variable on each render
是的,这是正确的。在 Example2 中,它创建了 1 个变量,但是 React 中的状态是不可变的。这意味着,每次渲染时,整个对象都会被复制到一个临时变量中,销毁并再次创建。由于这个事实,建议不要在状态中存储巨大的对象,因为它会对您的性能产生不利影响。