一、项目搭建
首先,确保你已经安装了 Node.js 和 npm(Node 包管理器)。然后创建一个新的 React 项目,可以使用create-react-app
工具来快速搭建项目框架。打开终端,执行以下命令:
npx create-react-app todo-list-app
cd todo-list-app
将创建一个名为 todo-list-app
的 React 项目,并进入该项目目录。
二、项目结构及组件规划
在 src
目录下,我们可以规划以下几个主要组件:
TodoList.js
:负责展示整个待办事项列表,包括每个待办事项的展示以及相关操作按钮(编辑、删除)。TodoItem.js
:用于展示单个待办事项的详细信息,如事项内容、是否完成状态等。AddTodo.js
:提供输入框和按钮,让用户能够添加新的待办事项。
三、实现 AddTodo
组件
在 src
目录下创建 AddTodo.js
文件,代码如下:
import React, { useState } from 'react';
const AddTodo = ({ addTodo }) => {
const [todoText, setTodoText] = useState('');
const handleInputChange = (e) => {
setTodoText(e.target.value);
};
const handleAddTodo = () => {
if (todoText.trim()!== '') {
addTodo(todoText);
setTodoText('');
}
};
return (
<div>
<input
type="text"
placeholder="添加新的待办事项"
value={todoText}
onChange={handleInputChange}
/>
<button onClick={handleAddTodo}>添加</button>
</div>
);
};
export default AddTodo;
在这个组件中,我们使用了 React 的 useState
钩子来管理输入框中的待办事项文本状态。当用户在输入框中输入内容时, handleInputChange
函数会更新 todoText
的状态。当用户点击 “添加” 按钮时, handleAddTodo
函数会检查输入的文本是否为空,如果不为空则通过调用从父组件传递过来的 addTodo
函数将新的待办事项添加到列表中,并清空输入框。
四、实现 TodoItem
组件
创建 TodoItem.js
文件,代码如下:
import React, { useState } from 'react';
const TodoItem = ({ todo, updateTodo, deleteTodo }) => {
const [isEditing, setIsEditing] = useState(false);
const [editedText, setEditedText] = useState(todo.text);
const handleEditClick = () => {
setIsEditing(true);
};
const handleSaveClick = () => {
if (editedText.trim()!== '') {
updateTodo(todo.id, editedText);
setIsEditing(false);
}
};
const handleCancelClick = () => {
setIsEditing(false);
setEditedText(todo.text);
};
const handleDeleteClick = () => {
deleteTodo(todo.id);
};
if (isEditing) {
return (
<div>
<input
type="text"
value={editedText}
onChange={(e) => setEditedText(e.target.value)}
/>
<button onClick={handleSaveClick}>保存</button>
<button onClick={handleCancelClick}>取消</button>
</div>
);
}
return (
<div>
<span>{todo.text}</span>
<button onClick={handleEditClick}>编辑</button>
<button onClick={handleDeleteClick}>删除</button>
</div>
);
};
export default TodoItem;
这个组件用于展示单个待办事项。它接收一个 todo
对象作为属性,包含待办事项的 id
和 text
等信息。同时,它还接收 updateTodo
和 deleteTodo
函数用于更新和删除待办事项。组件内部使用 useState
钩子来管理编辑状态和编辑后的文本状态。当用户点击 “编辑” 按钮时,会进入编辑模式,显示输入框供用户修改待办事项内容。修改完成后,点击 “保存” 或 “取消” 按钮可相应地保存修改或取消编辑操作。点击 “删除” 按钮则会调用 deleteTodo
函数删除该待办事项。
五、实现 TodoList
组件
创建 TodoList.js
文件,代码如下:
import React, { useState } from 'react';
import TodoItem from './TodoItem';
import AddTodo from './AddTodo';
const TodoList = () => {
const [todos, setTodos] = useState([]);
const addTodo = (text) => {
const newTodo = {
id: Date.now(),
text: text
};
setTodos([...todos, newTodo]);
};
const updateTodo = (id, text) => {
const updatedTodos = todos.map(todo => {
if (todo.id === id) {
return {...todo, text: text };
}
return todo;
});
setTodos(updatedTodos);
};
const deleteTodo = (id) => {
const remainingTodos = todos.filter(todo => todo.id!== id);
setTodos(remainingTodos);
};
return (
<div>
<h1>待办事项列表</h1>
<AddTodo addTodo={addTodo} />
{todos.map(todo => (
<TodoItem
key={todo.id}
todo={todo}
updateTodo={updateTodo}
deleteTodo={deleteTodo}
/>
))}
</div>
);
};
export default TodoList;
在 TodoList
组件中,我们首先使用 useState
钩子来管理整个待办事项列表的状态,初始值为空数组。 addTodo
函数用于添加新的待办事项,它创建一个新的待办事项对象,包含一个唯一的 id
(这里使用当前时间戳作为 id
)和用户输入的文本内容,然后将新的待办事项添加到列表中。 updateTodo
函数用于更新指定 id
的待办事项内容,它通过遍历列表找到对应的待办事项并更新其文本内容。 deleteTodo
函数用于删除指定 id
的待办事项,它通过过滤掉要删除的待办事项来更新列表。
最后,在组件的返回值中,我们展示了一个标题 h1
,然后渲染了 AddTodo
组件用于添加新事项,以及通过 map
函数遍历 todos
列表,为每个待办事项渲染一个 TodoItem
组件。
六、在 App.js
中使用 TodoList
组件
打开 App.js
文件,将默认的代码替换为以下内容:
import React from 'react';
import TodoList from './TodoList';
function App() {
return (
<div className="App">
<TodoList />
</div>
);
}
export default App;
这里我们只是简单地在 App
组件中引入并渲染了 TodoList
组件。
七、样式美化(可选)
为了让待办事项列表看起来更加美观,可以添加一些 CSS 样式。在 src
目录下创建一个 styles.css
文件(或者在已有的 CSS 文件中添加样式),以下是一些简单的示例样式:
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
h1 {
text-align: center;
color: #333;
}
div {
margin: 10px;
}
input[type="text"] {
padding: 5px;
border: 1px solid #ccc;
border-radius: 3px;
}
button {
padding: 5px 10px;
border: none;
border-radius: 3px;
background-color: #007BFF;
color: white;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
这些样式会设置页面的字体、背景颜色,以及输入框、按钮等元素的外观和交互效果。要让这些样式生效,需要在 App.js
或其他合适的地方引入这个 CSS 文件,例如:
import React from 'react';
import TodoList from './TodoList';
import './styles.css';
function App() {
return (
<div className="App">
<TodoList />
</div>
);
}
export default App;
通过以上步骤,我们就使用 React 实现了一个简单的待办事项列表,用户可以方便地添加、编辑和删除待办事项。在实际应用中,还可以进一步扩展功能,比如添加待办事项的优先级设置、截止日期设置等,以满足更多的需求。
补充:介绍一些常见的 React 开发工具
一、代码编辑器
- Visual Studio Code(VS Code)
-
特点:
- 轻量级且功能强大,拥有丰富的插件生态系统。对于 React 开发,有许多插件可以增强开发体验。例如,“ESLint” 插件可以帮助检查代码中的语法错误和潜在的问题,确保代码风格的一致性。
- 支持智能代码补全,在编写 React 组件和使用相关 API 时,能够根据上下文自动提示可能的属性、方法和组件名称。比如,当编写一个
React.Component
的子类时,它会提示render
方法等生命周期方法。 - 内置了强大的调试支持。可以通过配置
launch.json
文件,方便地调试 React 应用,无论是基于浏览器的应用还是使用 Node.js 环境的服务端渲染应用。
-
使用场景:
- 适合各种规模的 React 项目开发,无论是小型的示例应用还是大型的企业级项目。几乎是大多数 React 开发者的首选编辑器。
-
- WebStorm
- 特点:
- 是一款功能全面的集成开发环境(IDE),提供了对 JavaScript 和 React 的深度支持。它有智能的代码导航功能,能够轻松地在不同的组件、模块和文件之间跳转。
- 具备出色的代码分析能力,可以检测出未使用的变量、潜在的内存泄漏等问题。例如,在使用 React Hooks 时,如果
useEffect
的依赖项设置不正确,它可以及时发现并提醒。 - 对于 React 组件的模板语法(如 JSX)和 CSS 样式的支持也很好。可以自动补全 CSS 类名,并且在编辑 JSX 时提供属性和标签的自动完成。
- 使用场景:
- 适合大型、复杂的 React 项目开发,尤其是团队合作的项目。它的代码检查和版本控制集成等功能可以提高团队的开发效率。
- 特点:
二、调试工具
- React DevTools
- 特点:
- 这是一款专门用于调试 React 应用的浏览器扩展工具,可用于 Chrome 和 Firefox 等主流浏览器。它可以让开发者查看 React 组件的层次结构,就像查看 DOM 树一样直观。
- 能够显示组件的当前状态(state)和属性(props)。例如,在一个包含多个嵌套组件的应用中,可以方便地查看每个组件内部的
state
值,以及从父组件传递过来的props
的具体内容。 - 支持在浏览器中直接修改组件的状态,这对于快速调试组件的不同状态下的行为非常有用。比如,可以修改一个列表组件的
state
中的数据,观察 UI 如何实时更新。
- 使用场景:
- 在开发和调试 React 应用的过程中,几乎全程都需要使用。无论是排查组件渲染问题、状态更新问题还是属性传递问题,它都是必不可少的工具。
- 特点:
- Chrome DevTools(适用于 React)
- 特点:
- 除了常规的用于调试 JavaScript、CSS 和 HTML 的功能外,对于 React 应用也有很大的帮助。可以使用 “Performance” 面板来分析 React 应用的性能,查看组件的渲染时间和重绘情况。
- 在 “Sources” 面板中,可以设置断点,调试 React 组件的生命周期方法和事件处理函数。例如,在
componentDidMount
方法中设置断点,查看组件挂载时的数据获取和初始化操作。
- 使用场景:
- 当需要深入分析 React 应用的性能问题,或者对组件的具体代码执行流程进行调试时,Chrome DevTools 是很好的选择。它可以和 React DevTools 配合使用,提供更全面的调试体验。
- 特点:
三、构建工具
- Create - React - App(CRA)
- 特点:
- 这是 Facebook 官方推出的用于快速搭建 React 应用的脚手架工具。它预先配置了许多开发和生产环境所需的设置,如 Webpack 用于模块打包,Babel 用于将 ES6 + 代码转换为浏览器兼容的代码。
- 提供了一个简单的开发服务器,支持热模块替换(HMR)。这意味着在开发过程中,当修改代码后,应用可以自动更新,而不需要手动刷新浏览器,大大提高了开发效率。
- 遵循最佳实践,默认的项目结构和配置方便开发者快速上手,并且可以通过 “eject” 命令来定制配置,不过 “eject” 操作是不可逆的。
- 使用场景:
- 适合初学者快速创建和启动 React 项目,也适用于小型到中型规模的项目开发。在不需要对构建工具进行复杂定制的情况下,是一种高效的选择。
- 特点:
- Webpack
- 特点:
- 是一个功能强大的模块打包工具,在 React 开发中被广泛使用。它可以将所有的 JavaScript、CSS、图片等资源打包成浏览器能够理解的格式。
- 支持各种插件和加载器(loader)。例如,对于 React 项目,可以使用
babel - loader
来处理 JSX 和 ES6 + 代码,使用css - loader
和style - loader
来处理 CSS 样式。 - 可以对打包过程进行高度定制,包括代码分割(Code Splitting),将应用的代码分成多个小块,实现按需加载,提高应用的性能和加载速度。
- 使用场景:
- 适合中大型 React 项目,尤其是需要对构建过程进行精细控制的情况。例如,当需要优化打包后的文件大小、实现懒加载或者集成其他类型的资源(如字体文件、SVG 等)时,Webpack 是必不可少的工具。
- 特点:
- Parcel
- 特点:
- 以其零配置的特点而闻名,对于 React 项目,它可以快速地进行打包和构建。它能够自动识别项目中的各种文件类型,如 JSX、CSS、HTML 等,并进行相应的处理。
- 支持热模块替换,开发体验较好。并且它的打包速度相对较快,能够提高开发效率。
- 使用场景:
- 适用于小型到中型的 React 项目,特别是在追求快速开发和简单构建的情况下。如果不想花费太多时间在构建工具的配置上,Parcel 是一个不错的选择。
- 特点:
补充:分享一些实用的 React 教程
慕课网:React 进阶 - 从基础走向高级的实用技巧与实战指南
- 内容简介:该教程深入讲解了 React 组件的高级应用,包括纯函数组件与类组件的对比和使用场景,以及 React 生命周期方法的详细介绍和高级场景应用 。还涵盖了状态管理与 Redux 实践,从 Redux 基础知识到在 React 应用中的集成与使用,以及 React Hooks 的高级应用,如
useState
、useEffect
的使用技巧和状态复用与优化等,最后还介绍了性能优化的方法,如批量渲染与React.memo
的使用 。 - 学习收获:通过学习,能够深入理解 React 的核心概念和高级特性,掌握复杂组件的构建和优化方法,提升 React 应用的开发效率和性能。
CSDN 博客:React 18【实用教程】(2024 最新版)
- 内容简介:全面介绍了 React 18 的相关知识,包括搭建开发环境,详细讲解了 JSX 语法,以及组件之间的各种传值方式,如父子组件传值、兄弟组件传值、越层组件传值等。还涵盖了缓存组件
memo
、Hooks 的各种用法,如useState
,useReducer
,useRef
,useEffect
,useContext
,useMemo
,useCallback
以及自定义 Hook 等,此外还有双向绑定表单、状态管理、路由管理、框架原理和性能优化等内容,并通过实战案例,如 tab 切换、纯前端列表排序等,帮助读者更好地理解和应用所学知识. - 学习收获:可以系统地学习 React 18 的新特性和实用技巧,全面提升 React 开发技能,能够独立开发功能丰富、性能优良的 React 应用。
知乎专栏:React 学习 - 入门教程
- 内容简介:从基础开始,先介绍了 JSX 语法,包括其基本用法和特点,如可以在 JSX 中嵌套变量、表达式等。然后讲解了元素渲染的原理和方法,以及组件和
props
的概念与使用,通过函数组件和类组件的示例,深入剖析了组件的复用性和数据传递。还详细阐述了state
和生命周期的相关知识,包括如何在类组件中使用state
来管理组件内部状态,以及componentDidMount
、componentWillUnmount
等生命周期方法的应用。此外,还涵盖了事件处理、条件渲染、列表渲染和表单处理等 React 开发中的常见知识点. - 学习收获:适合初学者快速入门 React,能够掌握 React 的基本概念和开发流程,为进一步深入学习和实践打下坚实基础。
CSDN 博客:React 教程 (详细版)
- 内容简介:首先介绍了 React 的概念和原生 JavaScript 在开发中的痛点,以及 React 的特点,如组件化模式、声明式编码、虚拟 DOM 和高效的 diffing 算法等。接着详细讲解了在 HTML 中使用 React 的方法,包括创建虚拟 DOM 的两种方式以及 JSX 语法的各种细节,如定义虚拟 DOM 时的注意事项、标签中引入 js 表达式的方法、行内样式的写法等。最后还介绍了 React 面向组件编程的相关知识,如组件的分类、组件实例对象的属性等.
- 学习收获:能够全面了解 React 的基础知识和开发要点,深入理解 React 的核心原理和优势,掌握 React 开发中的各种语法和技巧,提高开发效率和代码质量 。
知乎专栏:React 单元测试实例 - 快速上手指南
- 内容简介:主要讲解了如何为 React 代码编写单元测试,使用了 jest 和 react-testing-library 库,涵盖了编写单元测试的所有步骤,包括 describe 函数、it 函数、expect 语句块等关键组件的使用方法,以及如何对 React 组件的渲染、props 传递、事件处理等进行测试,还介绍了一些测试技巧,如跳过测试、只执行单个测试等.
- 学习收获:学会为 React 应用编写单元测试,提高代码的可靠性和可维护性,能够更好地保证项目的质量和稳定性。
补充:React 和 Vue 的主要区别
一、设计理念
- React:
- React 的设计理念更侧重于构建大型应用程序的可组合性和可维护性。它通过将用户界面(UI)拆分成一个个独立的、可复用的组件,这些组件就像积木一样,可以组合在一起构建复杂的 UI。例如,一个大型电商网站的商品列表、购物车、用户信息模块等都可以作为独立组件开发,然后组合成完整的页面。
- React 遵循函数式编程的思想,强调数据不可变(immutability)。这意味着一旦数据创建后就不能被修改,如果要更新数据,需要创建一个新的数据副本。这种方式使得 React 的状态管理更加可预测,方便调试和跟踪数据的变化。
- Vue:
- Vue 的设计理念是渐进式框架,它比较灵活,可以逐步应用到项目中。这意味着你可以在一个传统的 HTML 页面中,通过引入 Vue.js 文件,然后在 HTML 标签中使用 Vue 的指令(如
v - if
、v - for
)来实现数据绑定和 DOM 操作,而不需要一开始就构建一个完整的单页应用(SPA)架构。 - Vue 在设计上更加注重开发者的体验,尤其是对于初学者。它提供了一种直观的、类似于 HTML 模板的语法,使得开发者可以很容易地理解和上手。例如,在 Vue 模板中,通过
{{ variable }}
的方式就可以轻松地将数据绑定到 DOM 元素上。
- Vue 的设计理念是渐进式框架,它比较灵活,可以逐步应用到项目中。这意味着你可以在一个传统的 HTML 页面中,通过引入 Vue.js 文件,然后在 HTML 标签中使用 Vue 的指令(如
二、语法风格
-
React:
- React 使用 JSX(JavaScript XML)语法,这是一种 JavaScript 的语法扩展。JSX 允许开发者在 JavaScript 代码中直接编写类似 HTML 的标签结构,例如:
const element = <h1>Hello, React!</h1>;
- 这种语法使得 JavaScript 和 HTML 紧密结合,能够更方便地在组件中渲染 UI。但是,它需要通过像 Babel 这样的工具进行编译,才能在浏览器中运行。
- React 的组件可以是函数组件或者类组件。函数组件是无状态组件(在没有使用 Hooks 之前),只是接收输入(props)并返回 UI 元素。类组件则可以包含状态(state)和生命周期方法。例如,一个简单的函数组件:
function MyComponent(props) {
return <p>{props.text}</p>;
}
- 而使用类组件:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return <p>Count: {this.state.count}</p>;
}
}
-
Vue:
- Vue 的模板语法更接近传统的 HTML,它通过一系列的指令来扩展 HTML 的功能。例如,
v - bind
用于绑定属性,v - on
用于绑定事件。以数据绑定为例,在 Vue 中可以这样写:
- Vue 的模板语法更接近传统的 HTML,它通过一系列的指令来扩展 HTML 的功能。例如,
<div id="app">
<p>{{ message }}</p>
</div>
- 并且在 JavaScript 部分:
const app = new Vue({
el: '#app',
data: {
message: 'Hello, Vue!'
}
});
- Vue 组件主要是通过
Vue.component
方法或者单文件组件(.vue
文件)来定义。单文件组件将模板、样式和逻辑代码分别放在一个文件的不同部分,结构清晰。
三、性能优化
- React:
- React 通过虚拟 DOM(Virtual DOM)来优化性能。当组件的状态发生变化时,React 会先创建一个新的虚拟 DOM 树,然后通过比较新旧虚拟 DOM 树的差异(Diff 算法),只更新实际 DOM 中需要改变的部分。这个过程可以有效地减少对 DOM 的操作次数,提高性能。
- 另外,React 还提供了一些性能优化的方法,如
shouldComponentUpdate
生命周期方法(在类组件中)和React.memo
(在函数组件中),用于控制组件是否需要重新渲染。例如,React.memo
可以用来包裹一个函数组件,当组件的 props 没有发生变化时,阻止组件重新渲染。
const MyMemoizedComponent = React.memo(function MyComponent(props) {
// 组件内容
return <div>{props.text}</div>;
});
-
Vue:
- Vue 同样使用虚拟 DOM 来优化性能。它在编译模板时,会将模板转换为渲染函数,然后通过虚拟 DOM 来更新 DOM。Vue 的虚拟 DOM 更新机制也很高效,它会在组件级别进行细粒度的更新。
- Vue 还提供了一些性能优化的指令,如
v - once
,用于只渲染一次元素,之后即使数据发生变化也不再重新渲染。另外,在组件层面,通过合理地使用computed
属性和watch
选项,可以避免不必要的计算和 DOM 更新。例如,computed
属性会根据其依赖的数据自动缓存计算结果,只有当依赖数据发生变化时才会重新计算。
<div id="app">
<p v - once>{{ staticMessage }}</p>
</div>
const app = new Vue({
el: '#app',
data: {
staticMessage: 'This message will only be rendered once'
}
});
四、生态系统和社区支持
-
React:
- React 有一个庞大的生态系统,尤其在状态管理方面。Redux 是与 React 配合使用的非常流行的状态管理库,用于管理复杂应用程序中的全局状态。它遵循单向数据流的原则,使得状态的变化可预测、可追溯。例如,在一个大型的 React - Redux 应用中,所有的状态变更都通过派发(dispatch)动作(action)到 Reducer,然后 Reducer 根据动作类型更新状态,最后通过 React - Redux 的
connect
函数将状态和组件连接起来。 - 此外,React 还有许多用于路由管理的库,如 React - Router,用于处理单页应用中的页面导航。同时,由于 Facebook 的支持和广泛的社区贡献,React 的周边工具和库不断涌现,能够满足各种开发需求。
- React 有一个庞大的生态系统,尤其在状态管理方面。Redux 是与 React 配合使用的非常流行的状态管理库,用于管理复杂应用程序中的全局状态。它遵循单向数据流的原则,使得状态的变化可预测、可追溯。例如,在一个大型的 React - Redux 应用中,所有的状态变更都通过派发(dispatch)动作(action)到 Reducer,然后 Reducer 根据动作类型更新状态,最后通过 React - Redux 的
-
Vue:
- Vue 的生态系统也很丰富,它有自己的状态管理库 Vuex,与 Vue 应用的集成非常紧密。Vuex 同样遵循单向数据流,通过
store
来管理状态,组件可以通过dispatch
、commit
等方法来触发状态变更或者获取状态。 - 在路由方面,Vue - Router 是官方推荐的路由管理库,提供了简单易用的 API 来实现页面导航和路由参数传递等功能。Vue 的社区也很活跃,有许多插件和工具可以帮助开发者快速构建应用,如用于表单验证的
vee - validate
、用于 UI 组件库的 Element - UI 等。
- Vue 的生态系统也很丰富,它有自己的状态管理库 Vuex,与 Vue 应用的集成非常紧密。Vuex 同样遵循单向数据流,通过
五、学习曲线
-
React:
- 对于初学者来说,React 的学习曲线可能相对较陡。这主要是因为它的 JSX 语法和函数式编程概念对于没有接触过的开发者可能比较陌生。另外,React 在状态管理和复杂组件交互方面,需要开发者对一些高级概念(如 Redux 的工作原理、React 的生命周期等)有深入的理解,才能构建高效、可维护的应用。
- 然而,一旦掌握了这些概念,React 在处理大型、复杂的应用程序时能够提供很好的结构和可扩展性。
-
Vue:
- Vue 相对来说更容易上手,它的模板语法类似于 HTML,对于有 HTML 和 JavaScript 基础的开发者来说很容易理解。Vue 的文档也很清晰,示例丰富,能够帮助初学者快速入门。
- 但是,当应用程序变得复杂,涉及到深层次的组件嵌套、全局状态管理等问题时,Vue 的开发者也需要深入学习 Vuex、Vue - Router 等相关知识,以及理解 Vue 的响应式原理和性能优化策略。