React Hooks –[3] 提升状态
React Hooks –[3] 提升状态
本系列遵循 Epic React: React Hooks Workshop。
简介:React Hooks?
钩子是为我们保存状态(数据)或执行操作(副作用)的函数。每个都有一个独特的 API,并返回不同的值,甚至什么都没有。常见的有:
- 反应.useState
- React.useEffect
- React.useContext
- 反应.useRef
- React.useReducer
[3.1] 升降状态
通常,多个组件需要反映相同的变化数据。我们建议将共享状态提升到最接近的共同祖先。
https://reactjs.org/docs/lifting-state-up.html
好的,但这意味着什么?让我们尝试通过一个示例来理解这一点:
我们有一个显示组件,当用户输入这些输入时,它会显示用户名和他们最喜欢的动物。
这意味着我们必须跟踪名称组件中名称的状态、动物组件中动物的状态以及显示组件中两者的状态。
我们可以通过将状态从动物和名称提升到应用程序(它们最接近的共同祖先)来做到这一点。这意味着:我们在应用程序中设置名称和动物的状态,并将它们作为道具传递给它们的函数和显示函数。应用程序拥有共享状态,并成为“真相的来源”。
您正在提升树中较低的状态,并将其提升到树中较高的位置。
肯特·C·多兹
它看起来像这样:
函数名( **{名称,onNameChange}** ) {
返回 (
<div>
<label htmlFor="name">姓名:</label>
<input id="name" **值={name} onChange={onNameChange}** />
</div>
)
} 功能最爱动物( **{动物,onAnimalChange}** ) {
返回 (
<div>
<label htmlFor="animal">最喜欢的动物:</label>
<input id="animal" **价值={动物} onChange={onAnimalChange}** />
</div>
)
} 功能显示( **{名称,动物}** ) {
返回<div>{`嘿${name},你最喜欢的动物是:${animal}!`}</div>
} 函数应用程序(){
**const [name, setName] = React.useState('')
const [动物,setAnimal] = React.useState('')** 返回 (
<form>
<Name **name={name} onNameChange={event = > setName(event.target.value)}** />
<FavoriteAnimal **名称={动物} onAnimalChange={事件 = > setAnimal(event.target.value)}** />
<Display **名称={名称} 动物={动物}** />
</form>
)
} 导出默认应用
关于一些命名
onNameChange 和 onAnimalChange 可以称为其他任何名称,这种命名方式只是一种约定。
总结一下,来自文档:
对于 React 应用程序中发生变化的任何数据,都应该有一个单一的“事实来源”。通常,状态首先添加到需要它进行渲染的组件中。然后,如果其他组件也需要它,您可以将它提升到它们最近的共同祖先。与其尝试在不同组件之间同步状态,不如依赖 自上而下的数据流 .
(……)
如果某些东西可以从 props 或 state 派生出来,那么它可能不应该在 state 中。
[3.2] 共置状态
将代码放置在尽可能靠近相关的位置
https://kentcdodds.com/blog/state-colocation-will-make-your-react-app-faster
那么什么是托管?我们为什么关心?
托管是使“事物”尽可能靠近它们相关的地方的做法。例如,它可能会在代码附近放置注释。在这种情况下,它是关于 保持状态接近它的组件 . (Kent 详细介绍了托管 这里 )
有时可能需要一起更新组件,例如我们在上一个主题中的示例。但是很多时候你不需要同时更新它们。
假设我们只想展示动物。我们可以将名称保留在原处,仅更新显示组件。但是,当我们只想重新渲染动物时,一切都会重新渲染。
在这种情况下,由于 display 函数不再关心 name 状态,我们可以将它放在 name 函数中。现在,当我们更新显示组件时,名称不会被重新渲染。
所以我们按顺序本地化我们的状态 获得绩效 , 但是也 使我们的代码更易于维护 .如果我们需要更新名称,一切都在附近,我们不会浪费时间搜索它。
它看起来像这样:
函数名称(){
**const [name, setName] = React.useState('')**
返回 (
<div>
<label htmlFor="name">姓名:</label>
<input id="name" **value={name} onChange={event = > setName(event.target.value)}** />
</div>
)
} 功能最爱动物( **{动物,onAnimalChange}** ) {
返回 (
<div>
<label htmlFor="animal">最喜欢的动物:</label>
<input id="animal" **价值={动物} onChange={onAnimalChange}** />
</div>
)
} 功能显示( **{动物}** ) {
返回<div>{`你最喜欢的动物是: **${动物}** !`}</div>
} 函数应用程序(){ **
const [动物,setAnimal] = React.useState('')** 返回 (
<form>
<Name />
<FavoriteAnimal **名称={动物} onAnimalChange={事件 = > setAnimal(event.target.value)}** />
<Display **名称={名称} 动物={动物}** />
</form>
)
} 导出默认应用
下面是 Kent C Dodds 的图表,帮助决定应该将组件的状态放置在何处、何时将其提升和共置
flowchart by Kent C Dodds
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明