jun*_*lin 1 javascript ecmascript-6 reactjs react-hooks
假设currentSelected在 React 功能组件中有一个独立于UI 的状态。它存储当前选择的项目,并将在某个时间使用。
有两种方法可以在useRef hook组件外存储状态或模块范围。
useRef 钩子:
function Example() {
const currentSelected = useRef()
useEffect(() => {
// access currentSelected state
})
function handleClick(item) {
currentSelected.current = item
}
return (
<ul>
{items.map(item => <li onClick={() => handleClick(item)}>item.name</li>)}
</ul>
)
}
Run Code Online (Sandbox Code Playgroud)
模块范围:
let currentSelected = null
function Example() {
useEffect(() => {
// access currentSelected state
})
function handleClick(item) {
currentSelected = item
}
return (
<ul>
{items.map(item => <li onClick={() => handleClick(item)}>item.name</li>)}
</ul>
)
}
Run Code Online (Sandbox Code Playgroud)
哪种方法更适合存储与 UI 无关的状态currentSelected?
useRef以及模块作用域在存储状态方面的应用场景是什么?
========== 更新 ==========
UI 独立性意味着您不想在更新状态后触发重新渲染。相比之下,UI 相关的状态就是这样做的。
useRef和模块作用域变量的区别为了完整起见,我也将投入useState。
useState:绑定到组件实例并通过setter函数在更改时触发渲染的不可变数据。useRef:可变数据也与组件实例相关联,但不会在更改时触发任何渲染。useRef如果您多次安装一个组件,例如在两个页面上使用它,useRef将确保每个组件实例都有自己的可变值。
// Here, the Example component could be used in multiple places
// and each instance would successfully keep its own state while
// not triggering renders on changes.
function Example() {
const currentSelected = useRef()
useEffect(() => { /* access currentSelected state */ })
return (
<ul>
{items.map(item => (
<li onClick={() => { currentSelected.current = item }}>{item.name}</li>
))}
</ul>
)
}
Run Code Online (Sandbox Code Playgroud)
如果您正在寻找类似单例模式或类似静态的变量,例如对于某种应用程序范围的共享数据,那么模块范围变量将使这成为可能,就像在任何普通 JS 模块中一样。
// Here, the count value will be initialized once and then shared between every
// instances across the app, ever.
let count = 0;
function Example() {
// Won't trigger a render, so some Example instance could still show the old value.
count += 1;
return <span>Combined renders of all the Example components: {count}</span>;
}
Run Code Online (Sandbox Code Playgroud)
请注意,它不会在count更改时触发渲染,因此您不应该那样使用它。
如果仅在组件仅安装一次的地方使用一次,则两种模式的行为似乎相似,但最终,某些东西触发重新安装只是时间问题,然后您将面临一个奇怪的错误。
在对包含模块作用域变量的模块进行单元测试时,您也可能会遇到问题,因为它可能无法在测试用例之间正确重置。一个快速的解决方法是只导出变量并让测试用例更改其值,但注意不要在其他任何地方更改它。虽然这应该作为个案评估。
| 归档时间: |
|
| 查看次数: |
622 次 |
| 最近记录: |