React
学习视频
12. Props, Immutability, and One-Way Data Flow_哔哩哔哩_bilibili
React笔记
前置知识
这里写了常用到的 js知识
|
概述
React 是用于构建用户界面的 JavaScript 库。
它提供了组件、状态管理、生命周期方法等功能来帮助开发者构建复杂的前端应用
其主要功能是实现后端数据与前端页面的即时更新,同时减少单一使用js
时的繁冗工作量
项目结构
创建项目:
方法1:
a. 安装 Node.js 和 npm(Node.js 包管理器)。
b. 打开终端或命令提示符。
c. 运行以下命令来创建一个新的 React 应用程序:
|
方法2:使用 Vite
Vite 是一个轻量级的构建工具,它提供了快速的冷启动和热更新。它支持 TypeScript、CSS 预处理器和许多其他功能。
|
文件结构如下
|
React 三要素
1. 组件(Component)
组件是 React 的基础构建块,每个 React 应用都是由一个个组件组合而成的。React为每一个组件渲染一个视图,这些视图组成UI。每个组件都拥有自己的 “数据” “(js)逻辑” “外观”
- 类组件:通过 ES6 的类来定义,包含状态(state)和生命周期方法。
- 函数组件:React 16.8 之后推荐的方式,使用函数定义组件并结合钩子(Hooks)来管理状态和生命周期。
组件不可嵌套
示例:
|
什么是 JSX ?
jsx是一种声明语法,用来描述组件的外观,根据数据和逻辑工作。通常与 React 一起使用,允许在 JavaScript 代码中编写类似 HTML 的标签
- 类 HTML 的语法:
- JSX 允许在 JavaScript 代码中嵌入类似 HTML 的标签,使得编写用户界面时更加直观和简洁。虽然看起来像 HTML,但 JSX 实际上会被编译成 JavaScript 函数调用。
- 支持表达式:
JSX 中可以使用 JavaScript 表达式,通过{}包裹
const name = 'Alice';
const element = <h1>Hello, {name}!</h1>;
- 必须返回一个父元素:
在 JSX 中,所有标签必须被一个父级元素包裹。例如:
return (
<div>
<h1>Title</h1>
<p>Description</p>
</div>
);
- 样式和属性的处理:
在 JSX 中,class属性被替换为
className
,style属性接受一个对象。例如:
<div className="container" style={{ color: 'red' }}>Hello</div>
2. 状态(State)
状态是组件内部的数据,它决定了组件的行为和显示的内容。
状态是可变的,随着用户的交互或其他事件触发,它会发生变化并重新渲染组件。
在类组件中,状态通过 this.state
来管理,在函数组件中使用 useState
钩子来管理。
什么是钩子?
在 React 中,钩子就是use开头的状态组件,允许你在函数组件中使用状态和其他 React 特性,而不需要编写类组件。
常见的 React 钩子有:
useState
:用于在函数组件中添加状态变量。useEffect
:用于执行副作用操作(如数据获取、订阅或手动更改 DOM)。useContext
:用于在组件树中共享数据,而无需逐层传递 props。
怎么使用状态
什么时候创建状态?
需要存储数据?
数据会发生变化吗
- 不会 => const 常量即可
是否可以从现有的道具/状态中计算?
- 会 => 派生状态(derive state)
更新状态是否需要重新渲染组件?
- 不会 => 使用Ref (像普通状态一样持久的保持数据,但无需重新渲染组件)
- 使用useState创建一个状态,并放置在组件中
在哪里使用状态?
当前组件、通过道具传递给子组件、将状态传递给同级组件的公共父组件中去(状态上移)、所有组件使用(全局状态)
派生状态
派生状态就是简单地从一个现有状态或者道具中计算出来的状态
|
3. 属性(Props)
props
是组件之间传递数据的方式。
父组件可以通过 props
向子组件传递数据,子组件无法修改 props
,它们是只读的。props
的主要作用是让组件的渲染更加灵活和可复用。
在传递中,我们可以使用 js 中的重构
来传递对象的名称而不是props
,但是不要忘记使用{}
注 : React是单向数据流,数据只能从父组件流向子组件
示例:
|
子代道具
在 React 中,子代道具(Children Props) 是指通过 props.children
传递的内容,它允许父组件将嵌套在其内部的 JSX 代码或组件传递给子组件。它提供了一种灵活的方式来构建可复用的组件,使得父组件可以决定子组件的内部内容,而不需要在子组件中明确指定。
示例:
|
三要素关系总结:
- 组件 是 UI 的基本单元,通过组合形成完整的应用。
- 状态 是组件内部的动态数据,控制着组件的行为和显示。
- 属性(props) 用于在组件间传递数据,通常是父组件传递给子组件的数据。
状态与道具有什么区别?
状态(state):状态是组件内部管理的数据,数据归创建他的组件所有,它可以看作组件的存储,可以用来长期保存数据。状态可以在组件内部被修改(通过
setState
或useState
),并会在变化时触发组件重新渲染,用来控制组件的行为、渲染和交互。
- 用于存储组件内部动态变化的数据,比如用户输入的表单值、加载数据的结果、组件的交互状态(如打开或关闭某个UI元素)。
- 当状态发生变化时,React会自动触发两个组件的重新渲染
道具(props):道具是从父组件传递给子组件的数据,数据被父组件所有,可以把它想象函数参数。因为它是只读的,子组件无法直接修改它。当子组件收到更新的props时,也会重新渲染组件
- 道具主要用来让组件间进行静态数据传递,通常是父组件将数据通过道具传递给子组件,子组件根据道具的值渲染。
- 当道具的值在父组件中发生变化时,子组件会重新渲染。
怎么渲染列表(rendering a list)
概念:可以理解为创建一个数组,并为数组里的每个元素创建组件
通常我们会使用数组的 map()
方法来生成列表项。每个列表项需要一个唯一的 key
属性,以帮助 React 识别和优化列表中的元素
示例:
|
条件渲染
方法一:使用 && 运算符的短路逻辑,在特定条件下选择内容
示例:
|
方法2:使用三元运算符
示例:
|
方法三:多重返回
示例:
|
React Fragment(react 片段)
概念:React.Fragment
是 React 中用于包裹多个子元素而不额外生成 HTML 元素的组件。
通常在 JSX 中,如果你返回多个元素,它们需要被一个父级元素<div></div>
包裹,而 React.Fragment
可以在不生成额外 DOM 节点的情况下包裹这些元素。
示例:
|
如何在React中使用表单?
怎么判断是否需要使用表单?
- 用户输入:如果你需要用户输入数据,比如添加待办事项,那么你需要一个表单。表单可以包含输入框、文本域、选择框等元素,让用户输入信息。
- 提交操作:如果你需要用户提交数据,比如添加待办事项后保存到列表中,那么你需要一个表单。表单通常包含一个提交按钮,用户点击后触发数据提交。
- 数据验证:如果你需要对用户输入的数据进行验证,比如检查待办事项是否为空,那么你需要一个表单。表单可以包含验证逻辑,确保用户输入的数据符合要求。
- 状态管理:如果你需要管理用户输入的状态,比如输入框的值,那么你需要一个表单。表单可以包含状态管理逻辑,确保用户输入的数据能够被正确处理。
- 事件处理:如果你需要处理用户输入的事件,比如输入框的
onChange
事件,那么你需要一个表单。表单可以包含事件处理逻辑,响应用户的操作。
表单完整代码(以ToDoList为例):
|
渲染列表
{Array.from({length: 20}, (_, i) => i+1).map ((num) => ( <option value={num} key={num}> {num} </option>))}
:
利用Array.from()
生成一个数组,并通过map()
来遍历数组,动态生成一组<option>
标签
onChange
:当用户在输入框中输入内容时,onChange
事件会触发,更新React状态,从而动态更新表单值
如何将表单中的数据导入事件?
常见的React事件类型:
- **
onClick
**:点击事件- **
onChange
**:表单元素(如输入框、选择框)的值改变事件- **
onSubmit
**:表单提交事件- **
onKeyDown
、onKeyUp
**:键盘按下、松开事件- **
onMouseEnter
、onMouseLeave
**:鼠标进入、离开事件
受控元素
在React中,使用受控组件可以将HTML表单中的数据与组件的状态(state
)直接绑定,从而避免直接操作DOM。这样做的好处是表单数据的更新和管理完全交由React来处理,无需手动获取DOM元素的值
三个步骤:
设置状态
const [description, setDescription] = useState('');
- 目的:创建一个变量来存储用户输入的值,并在用户与表单交互时,React能够追踪和管理这个值。
绑定变量 通过
value
属性,将表单元素(例如<input>
或<textarea>
)的值与刚刚创建的状态变量绑定。这样,表单的值由状态控制,React状态和UI之间建立了双向绑定关系。- 操作:在表单元素上使用
value={description}
,使输入框的值与description
状态保持同步
- 操作:在表单元素上使用
更新状态
onChange={(e) => setDescription(e.target.value)}
,当用户在表单元素中输入内容时,onChange
事件会触发。此时,你可以使用setDescription
函数更新状态,确保状态随用户输入的变化而改变。事件处理函数将接收事件对象,通过e.target.value
获取表单元素的新值。操作:在
onChange
事件处理函数中调用setDescription(e.target.value)
,将表单的新值更新到状态中js小知识
在
onChange={(e) => setDescription(e.target.value)}
这段代码中,e
是一个事件对象(Event Object),它代表了当前正在发生的事件。在 JavaScript 中,当事件(如点击、输入等)发生时,浏览器会创建一个事件对象,该对象包含了与该事件相关的所有信息。在这个特定的例子中,
e
是一个合成事件(Synthetic Event)对象,它是 React 为了兼容不同浏览器而创建的一个抽象层。合成事件对象封装了原生浏览器事件,并提供了一个统一的接口,使得开发者可以编写跨浏览器的代码。e.target
是事件的目标元素(Event Target),即触发事件的 DOM 元素。在这个例子中,e.target
是输入框(input)元素。e.target.value
是输入框元素的当前值(Value),即用户输入的内容。