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 about where to put react state, by Kent C Dodds

flowchart by Kent C Dodds

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/24458/50061008

posted @ 2022-09-10 08:51  哈哈哈来了啊啊啊  阅读(63)  评论(0编辑  收藏  举报