(先赞后看,已成习惯(bushi))这段时间,也是学习了一点React相关的知识,想着来写一篇文章总结一下对这段时间的学习以及学习成果,各位大佬看看有什么不足之处,欢迎指导~~~
前言(不用看):前端技术的不断发展,现代 Web 应用已经告别了传统的手动操作 DOM 和底层 API,转向了更加高效和灵活的数据驱动界面开发。React,作为最受欢迎的前端框架之一,利用组件化和响应式数据流,使得开发者能够专注于业务逻辑,而不是繁琐的 DOM 操作。
此文章将以 React 中的 Todo List 组件为例,深入剖析如何通过组件化思想、数据驱动的方式来构建一个响应式的 Web 应用。
项目的初始化与工程化:vite + React
在开始编写 React 项目之前,我们需要先进行项目初始化。现代前端开发离不开良好的构建工具,vite 是目前非常流行的前端构建工具之一,它提供了快速的开发环境和优化的打包性能。
** 创建一个React项目**
既然是React项目,那我们该如何创建呢? 下面跟着我一起来敲一敲这段神秘的代码吧!
- npm init vite 按vite模版初始化一个React项目
- 为我们的项目取一个名字TodoListComponent
- 选择React项目,语言为JS
- npm i 安装依赖
- npm run dev 启动项目,打开端口
React 初体验:组件化开发与状态管理
React 的核心思想是组件化。每个组件都是完成开发任务的最小单元,它将 HTML、CSS 和 JavaScript 结合在一起,封装成一个功能单元。让我们从创建一个简单的 Todo List 组件开始,一起来快速体验一下 React 的组件化开发吧!!
1. 组件是最小的开发单元
在 React 中,组件(Component)就是一个函数function(),每个组件就像一个个小功能块,并且这个功能块是独立的、被封装的。举个栗子,相信大家都拼过乐高积木吧,React 一个个组件就像一块块乐高积木。在开发React业务时,一个个大大小小的组件也就构成了我们的项目。 下面是个组件的例子
js
// 函数组件示例
function MyComponent() {
return <h1>Hello, React!</h1>;
}
在JS中,组件通常为函数式组件,由html,css,js共同构成,并且组件可以被复用和嵌套,在一个团队型业务开发中,你写的组件可以供全队的成员使用,同时你也可以使用其他团队成员的组件,是不是非常方便?
下面我们就开始构建jsx项目吧(jsx实则为js)
javascript
jsx
import { useState } from 'react';
function TodoList() {
const [todos, setTodos] = useState([
{ id: 1, text: '吃饭', completed: false },
]);
const handleAdd = (text) => {
setTodos([
...todos,
{ id: todos.length + 1, text, completed: false },
]);
};
return (
<div>
<h1>Todo List</h1>
{/* 表单组件 */}
<TodoForm onAdd={handleAdd} />
{/* 列表组件 */}
<Todos todos={todos} />
</div>
);
}
这是什么东西???我的脑袋好像不管用了。 下面我就来逐步分析一下吧
import { useState } from 'react'; 此代码意思是从react中导入一个为useState的hook, 那么有什么用?let's go!
其实useState是一个函数,此函数接受一个初始状态作为参数值,返回的是一个数组,数组的第一元素是当前的状态值,第二个元素是一个函数,可以用来更新当前状态
举个例子 const [todos, setTodos] = useState('todo') todos里面放的是todo setTodo可以和后续的定时器一起用来修改当前的状态值
下面我们来解释一下return里面的内容吧!期待一下(*❦ω❦)
-
<Todos />是另一个自定义子组件,负责展示待办事项列表。todos是父组件TodoList中的状态变量,存储了所有待办事项的数据(包括每个待办事项的id、text、completed等)。 -
todos={todos}:这是将todos作为 prop 传递给Todos组件。Todos会接收到这个todos数据,并在其内部渲染所有待办事项。 -
<TodoForm />是一个自定义的子组件,它负责展示一个表单界面,允许用户输入新的待办事项。 -
onAdd={handleAdd}:这里是通过 props 将父组件(TodoList)中的handleAdd方法传递给TodoForm组件。handleAdd是父组件中的一个方法,它负责处理新任务的添加逻辑。
具体来说,TodoForm 会展示一个输入框和一个提交按钮,用户输入任务后点击提交按钮时,handleAdd 被调用,TodoForm 通过 onAdd 这个 prop 将数据(比如新任务的内容)传递回 TodoList,然后 TodoList 更新其 todos 状态,重新渲染界面。
在这个例子中,TodoList 是一个 React 组件,它包含了一个 useState 钩子来存储和更新 todos 数据。你可以看到,组件通过 return 语句返回了一段 HTML,同时return里面又包含两个自定义的子组件,并通过 {todos.map(...)} 显示了所有待办项。
2. 数据驱动界面
在 React 中,数据状态 state 是自动驱动 UI 更新的关键。当 state 发生变化时,React 会重新渲染组件并更新视图,确保页面始终保持最新的状态。
php
jsx
复制编辑
const [todos, setTodos] = useState([
{ id: 1, text: '吃饭', completed: false },
]);
// 添加新任务
const handleAdd = (text) => {
setTodos([
...todos,
{ id: todos.length + 1, text, completed: false },
]);
};
通过 useState 我们可以轻松地管理组件中的数据状态,并通过 setTodos 方法来更新它。一旦数据发生变化,React 会自动更新页面中与之相关的部分,省去了手动操作 DOM 的麻烦。
3. 数据和 UI 绑定
React 中的模板语法非常直观,通过 {} 来绑定数据。这使得数据和视图的同步变得非常简单。我们不需要手动去操作 DOM,React 会根据数据的变化自动更新视图。
javascript
jsx
复制编辑
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
在这个例子中,todos.map() 遍历了 todos 数组,并动态渲染每个待办事项。如果我们添加一个新的待办项,React 会自动更新视图,展示新的列表项。
模块化开发:拆分组件与职责划分
随着项目的复杂度增加,组件化开发的优势会逐渐显现。在大型项目中,我们往往需要将组件进行拆分,每个组件只负责一个功能或者一个页面部分。
1. 拆分组件
在 Todo List 应用中,我们可以将不同的功能拆分成多个组件,例如:
TodoForm:负责添加新任务的表单组件TodoItem:负责渲染单个待办项TodoList:负责显示任务列表的组件
2. 组件传值与通信
React 中的组件之间通过 props 传递数据,父组件向子组件传递数据,而子组件则通过触发回调函数来与父组件进行通信。
ini
jsx
function TodoForm({ onAdd }) {
const [text, setText] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
onAdd(text);
setText('');
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<button type="submit">Add</button>
</form>
);
}
在 TodoForm 组件中,我们通过 props.onAdd 将任务添加的功能传递给父组件 TodoList。这种方式非常适合拆分复杂的 UI,提升代码的可复用性和可维护性。
这段代码是一个 React 组件 TodoForm,它负责渲染一个输入框和一个按钮,让用户输入待办事项,并通过点击按钮提交该事项。下面我将详细解释每一部分的内容,帮助你理解它的工作原理。
完整代码
ini
import { useState } from 'react';
function TodoForm(props) {
const onAdd = props.onAdd; // 从父组件接收到的 props
const [text, setText] = useState('打豆豆'); // useState 用来管理表单输入的状态
const handleSubmit = (e) => {
e.preventDefault(); // 阻止表单的默认提交行为
onAdd(text); // 调用父组件传递的 onAdd 函数并传递文本
}
const handleChange = (e) => {
setText(e.target.value); // 更新输入框的状态
}
return (
<form action="http://www.baidu.com" onSubmit={handleSubmit}>
<input
type="text"
placeholder="请输入待办事项"
value={text} // 双向绑定:输入框的值和状态 text 绑定
onChange={handleChange} // 输入框内容改变时更新状态
/>
<button type="submit">添加</button>
</form>
)
}
export default TodoForm;
逐行解释
1. useState 和初始化状态
arduino
const [text, setText] = useState('打豆豆');
- 这行代码通过
useState创建了一个名为text的状态变量,并使用setText来更新它。useState('打豆豆')为text提供了一个初始值'打豆豆',这意味着当表单第一次渲染时,输入框的值是'打豆豆'。 text状态用于存储输入框中的内容。
2. 从 props 获取 onAdd
ini
const onAdd = props.onAdd;
- 这行代码从父组件传递来的
props中获取onAdd函数。onAdd是一个回调函数,它会在表单提交时被调用,并将待办事项的文本(text)传递给父组件。父组件通常会用这个文本来更新其todos状态。
3. handleSubmit 函数:处理表单提交
scss
const handleSubmit = (e) => {
e.preventDefault(); // 阻止表单的默认提交行为
onAdd(text); // 调用父组件的 onAdd 函数,将文本传递给父组件
}
e.preventDefault():阻止表单的默认行为,防止页面刷新。通常,提交表单时浏览器会刷新页面,而e.preventDefault()可以阻止这个行为,让我们自己控制表单提交的动作。onAdd(text):表单提交时,调用onAdd回调函数,并将text作为参数传递给它。onAdd是父组件传递过来的一个函数,用来处理新待办事项的添加操作。
4. handleChange 函数:处理输入框变化
scss
const handleChange = (e) => {
setText(e.target.value); // 更新输入框的状态
}
- 这个函数在用户输入内容时被触发。每当用户在输入框中修改内容,
handleChange函数会被调用,它会更新text状态,使得text始终保持输入框的最新值。 e.target.value是输入框的当前值,将它传递给setText函数来更新状态。由于 React 是响应式的,更新状态后,组件会自动重新渲染,确保输入框显示的是最新的值。
5. 表单的 JSX 结构
ini
<form action="http://www.baidu.com" onSubmit={handleSubmit}>
<input
type="text"
placeholder="请输入待办事项"
value={text} // 双向绑定
onChange={handleChange}
/>
<button type="submit">添加</button>
</form>
-
<form action="http://www.baidu.com" onSubmit={handleSubmit}>: 这是一个表单元素,action="http://www.baidu.com"是默认的提交行为,但我们通过e.preventDefault()阻止了这个行为,改为自定义的提交逻辑。 -
<input type="text" placeholder="请输入待办事项" value={text} onChange={handleChange} />:type="text":这表示这是一个文本输入框。placeholder="请输入待办事项":输入框内的占位符提示用户输入待办事项。value={text}:这实现了 React 中的"受控组件"模式。输入框的值与text状态绑定,即text的值决定了输入框中显示的内容。onChange={handleChange}:当用户修改输入框内容时,handleChange会被调用,更新text状态。
-
<button type="submit">添加</button>:这是一个提交按钮,点击时会触发表单的onSubmit事件,从而调用handleSubmit函数。
双向绑定
在 React 中,表单控件通常被称为"受控组件"。这里的 双向绑定 是通过 value={text} 和 onChange={handleChange} 实现的:
value={text}:输入框的值由text状态来控制,因此输入框的内容总是与text状态同步。onChange={handleChange}:当用户修改输入框的内容时,handleChange会更新text状态,这样text状态总是与输入框中的内容保持同步。
小结
useState管理表单状态 :通过useState创建了一个状态text来保存输入框的内容。handleSubmit阻止表单提交 :通过e.preventDefault()阻止表单的默认提交行为,改为通过onAdd调用父组件的回调函数,传递用户输入的待办事项。handleChange更新状态 :每当输入框的内容发生变化时,handleChange会更新text状态,确保text始终包含输入框中的最新内容。- 受控组件 :通过将输入框的值绑定到
text状态,确保输入框的内容与状态同步,实现了双向绑定。
通过这种方式,TodoForm 组件有效地管理了用户输入,并将数据通过回调函数传递给父组件,完成了从用户交互到状态更新的整个流程。
总结
通过本文的讲解,我们深入了解了 React 的基本概念、组件化思想、状态管理和响应式界面开发。通过创建一个简单的 Todo List 组件,我们掌握了如何利用 React 构建一个数据驱动的 Web 应用。
React 的强大之处在于其组件化的架构和响应式的 UI 更新机制,使得开发者能够专注于业务逻辑而非 DOM 操作。随着项目的复杂度增加,拆分组件、模块化开发将成为必不可少的技能。掌握这些技能后,我们将能够高效地开发现代 Web 应用,构建出更加灵活、易维护的前端系统。
好啦,朋友们,今天我们的分享就到这里啦!!细节和干货还是拉满了的,有什么需要补充的地方也欢迎各位大佬在评论区指点一下!!