React hooks文档笔记(二) 添加交互性

news/2025/1/12 3:43:14/

添加交互性

  • 1. 事件传播
    • 1.1 停止传播
    • 1.2 阻止默认事件
  • 2. [Hook] useState 状态
  • 3. 渲染和提交
    • 3.1 触发渲染
    • 3.2 React渲染组件
    • 3.3 提交对 DOM 的更改
    • 3.4 浏览器绘制
  • 4. 渲染快照
    • 状态队列例子
  • 5. 更新state中的对象

1. 事件传播

js的事件流:

  • 事件捕获:从外到内
  • 事件冒泡:从内到外(默认模式)
export default function Toolbar() {return (<div className="Toolbar" onClick={() => {alert('You clicked on the toolbar!');}}><button onClick={() => alert('Playing!')}>Play Movie</button><button onClick={() => alert('Uploading!')}>Upload Image</button></div>);
}

点击任一按钮,它的 onClick 将首先运行,然后是父节点

的 onClick—— 所以会出现两条消息。
在这里插入图片描述
在这里插入图片描述 在这里插入图片描述如果你点击灰色区域本身,只有父
的 onClick 会运行。

1.1 停止传播

为阻止传播,可以在onClick中加一行引用事件参数e并调用e.stopPropagation()方法,此时当用户点击<button>时触发器该条语句,停止事件向外扩散,父节点<div>的onClick将不再触发。

1.2 阻止默认事件

e.preventDefault() 阻止默认行为
<form>:当内部按钮点击后,将默认重载整个页面

export default function Signup() {return (<form onSubmit={e => {e.preventDefault();    //点击按钮后将不再重载页面alert('Submitting!');}}><input /><button>Send</button></form>);
}

2. [Hook] useState 状态

形式:const [index, setIndex] = useState(默认值)

“[]”从useState解构出来两部分,

  1. 用于保留渲染之间数据的状态变量index
  2. 一个状态设置函数,setIndex用于更新变量触发 React 再次渲染组件

只能使用在组件,不能在条件、循环或其他嵌套函数中调用 Hooks,hook调用原理:
React报错#310复盘小结+hooks使用的场景+调用原理

只有 Hook 的调用顺序在多次渲染之间保持一致,React 才能正确地将内部 state 和对应的 Hook 进行关联。

useState内部:

React 为每个组件保存一组状态对。 它还维护当前对索引,该索引在渲染前设置为 0。 每次调用 useState 时,React 都会为您提供下一个状态对并递增索引。

let componentHooks = [];
let currentHookIndex = 0;
// How useState works inside React (simplified).
function useState(initialState) {let pair = componentHooks[currentHookIndex];if (pair) {// This is not the first render,// so the state pair already exists.// Return it and prepare for next Hook call.currentHookIndex++;return pair;}// This is the first time we're rendering,// so create a state pair and store it.pair = [initialState, setState];function setState(nextState) {// When the user requests a state change,// put the new value into the pair.pair[0] = nextState;updateDOM();}// Store the pair for future renders// and prepare for the next Hook call.componentHooks[currentHookIndex] = pair;currentHookIndex++;return pair;
}

3. 渲染和提交

举个例子:

组件是厨房里的厨师,用食材烹制美味佳肴。React 是一个服务员,负责接收客户的订单并为他们带来菜肴。这个请求和提供 UI 的过程分为三个步骤:

  1. 触发渲染(将客人的订单送到厨房)
  2. 渲染组件(在厨房准备订单)
  3. 提交给 DOM(将制作好的菜肴放在客户的桌上)
    在这里插入图片描述

3.1 触发渲染

组件渲染有两个原因:

  1. 初始渲染
    root.render(<App />);

  2. 组件(或其祖先之一)的state已更新

3.2 React渲染组件

export default function Gallery() {return (<section><h1>Inspiring Sculptures</h1><Image /><Image /></section>);
}
function Image() {return (<img src="xxx" alt="xxx" />);
}
  • 在初始渲染时,React 将调用根组件。
    <section><h1> 和两个<img>标签创建DOM节点

  • 对于后续的渲染,React 将调用状态更新触发渲染的函数组件
    React 将计算它们的哪些属性(如果有)自上次渲染以来发生了变化。 在下一步,即提交阶段之前,它不会对这些信息做任何事情。

3.3 提交对 DOM 的更改

  • 初始渲染时,React 将使用appendChild() DOM API 将它创建的所有 DOM 节点放在屏幕上。
  • 对于重新渲染,React 将应用最少的必要操作(在渲染时计算!)以使 DOM 匹配最新的渲染输出。

如果渲染之间存在差异,React 只会更改 DOM 节点。

举例:
Clock组件会随着父节点传入不同的props 参数 time 而重新渲染,但在input中输入‘1’,重新渲染时‘1’没有消失。

export default function Clock({ time }) {return (<><h1>{time}</h1><input /></>);
}

在这里插入图片描述在这里插入图片描述

这是因为随着time的改变, React 只更新了<h1>的内容,而没有触及<input>

3.4 浏览器绘制

渲染完成并且 React 更新 DOM 后,浏览器将重新绘制屏幕

4. 渲染快照

当 React 重新渲染一个组件时:

  1. React 再次调用你的函数。
  2. 您的函数返回一个新的 JSX 快照(使用该渲染中的state计算的,在快照中保持状态值“固定”)
  3. React 然后更新屏幕以匹配您返回的快照。

在这里插入图片描述
setState 只会为下一次渲染更改它

export default function Counter() {const [number, setNumber] = useState(0);return (<><h1>{number}</h1><button onClick={() => {setNumber(number + 1);setNumber(number + 1);}}>+2</button></>)
}

点击第一次后:
在这里插入图片描述
点击第二次后:
在这里插入图片描述
发现两次点击都只加了1

在第一次渲染期间,number是0,调用onClick:
第一个setNumber(number + 1)等价于 setNumber(0 + 1)
第二个setNumber(number + 1)等价于 setNumber(0 + 1)
React 准备在下一次渲染时更改number为1,也就是说设置状态为1了两次
在这里插入图片描述

在处理状态更新之前,React 会等到事件处理程序中的所有代码都已运行。这使您可以更新多个状态变量——甚至来自多个组件——而不会触发太多重新渲染

q: 在下一次渲染之前需要多次更新相同的state?


答: 可以传递一个函数,该函数根据前一个状态计算下一个状态队列
例如将上述例子替换为setNumber(n => n + 1);

n => n + 1更新函数(必须是纯函数并且只返回结果)

当您将它传递给状态设置器时:

  1. 在事件处理程序中的所有其他代码运行之后,React 将此函数排队等待处理。
  2. 在下一次渲染期间,React 遍历队列并为您提供最终的更新状态。
队列更新nreturns
n => n + 100+1=1
n => n + 111+1=2

状态队列例子

实现状态队列:https://codesandbox.io/s/0xym3z?file=/processQueue.js&utm_medium=sandpack

<button onClick={() => {setNumber(number + 5);setNumber(n => n + 1);setNumber(42);
}}>
队列更新nreturns
“replace with 5”0(unused)5
n => n + 155+1=6
“replace with 42”6(unused) 42

在下一次渲染期间,React 遍历状态队列:

  1. setNumber(number + 5): number是0,所以setNumber(0 + 5)。React 将“替换为5”添加到它的队列中。
  2. setNumber(n => n + 1): n => n + 1是一个更新函数。React 将该函数添加到它的队列中。
  3. setNumber(42): React 将“替换为42”添加到它的队列中。

5. 更新state中的对象

用 Immer 编写简洁的更新对象state逻辑:Immer编写简洁的更新state逻辑


http://www.ppmy.cn/news/666594.html

相关文章

CAD图纸的缩放——缩放上一个命令

使用此命令后&#xff0c;CAD视窗显示回到上一个缩放状态。 执行方式 (1&#xff09;单击菜单栏“视图→上一个”。如图&#xff1a; (2&#xff09;单击常用工具栏“缩放上一个”按钮。如图&#xff1a; (3&#xff09;在左下角命令行中输入“ZOOMP”按enter键。如图&#x…

cad等比例缩放快捷键_cad等比例缩放快捷键

大家好&#xff0c;我是时间财富网智能客服时间君&#xff0c;上述问题将由我为大家进行解答。 cad等比例缩放快捷键是S键C键。常用CAD的快捷键还有取消前一步操作CtrlZ、快速选择ALTTK、提取轮廓ALTMUP、重复执行上一步命令CtrlJ、打开特性对话框Ctrl1以及新建图形文件CtrlN等…

cad等比例缩放快捷键_原来CAD可以这样不等比例缩放!太方便了!这些技巧你都知道吗?...

我们在绘图看图的时候&#xff0c;经常都会用到CAD的缩放功能&#xff0c;所以缩放也是CAD中的一项常用操作&#xff0c;那么关于CAD的缩放技巧有哪些呢&#xff1f;今天小编就来跟大家分享一下在CAD中如何不等比例缩放和等比例缩放&#xff01; 一、不等比例缩放 1、夹点拉伸 …

CAD图纸缩放后怎么返回原点?

在对CAD图纸进行查看的时候&#xff0c;遇到太小或太大看不清的情况下&#xff0c;你是不是都是用鼠标来调整的呢&#xff1f;那么问题来了&#xff0c;到最后想要保存的时候你原本设置的比例大小忘了怎么办&#xff1f;下面教你快速解决这个问题的CAD制图教程。 1、在已安装CA…

cad放大_CAD图纸中局部放大图形的操作技巧

在使用CAD软件绘制CAD图纸的过程中&#xff0c;不管是机械图纸还是水暖电&#xff0c;局部详图对于表现细节很重要&#xff0c;CAD图纸中对细节放大是很重要的操作&#xff0c;那么具体该如何操作呢&#xff1f;接下来给大家详细介绍一下CAD图纸中局部放大图形的操作技巧吧&…

cad缩小_CAD中的文字如何缩放、分解?原来CAD中的文字还有这么多学问

CAD虽然是一个绘图软件&#xff0c;不过在绘图的时候&#xff0c;我们也会很经常用到文字标注&#xff0c;那么在CAD中&#xff0c;除了文字标注&#xff0c;文字的使用还有哪些技巧呢&#xff1f;今天小编就来跟大家分享一些简单的小技巧&#xff0c;想知道在CAD中如何缩放文字…

CAD梦想画图中的“缩放命令”

将选择的CAD图形按比例均匀的放大或缩小。可以指定基点和长度或输入比例因子来缩放对象&#xff0c;也可以为对象指定当前长度和新长度&#xff0c;大于1的比例因为为放大对象&#xff0c;介于0-1之间的比例因子为缩小对象。使用方法是执行“缩放”命令后&#xff0c;选取对象&…

cad等比例缩放快捷键_CAD中怎么才能将图案等比例缩放?

回答&#xff1a; CAD中怎么旋转参照物和等比例缩放 CAD中怎么旋转参照物和等比例缩放&#xff1f;CAD绘图中,经常需要对图块进行旋转和等比例缩放等操作,如下图所示&#xff0c;要使得图块中的红线与上面的红线平行并且长度相等。当两条红线中任意一条的转角和长度不为整数(存…