TypeScript+React Hooks+Redux构建Todo应用:全栈指南
2024-01-22 05:37:46
前言
在现代Web开发中,TypeScript、React和Redux是三个非常流行的工具。TypeScript是一种对JavaScript的超集,它可以帮助我们编写出更健壮、更易维护的代码。React是一个用于构建用户界面的JavaScript库,它以其声明式编程风格和高性能而著称。Redux是一个用于管理应用程序状态的JavaScript库,它以其可预测性、可调试性和可扩展性而备受欢迎。
本文将指导您使用这三个工具来构建一个完整的Todo应用。我们将从项目搭建开始,逐步学习如何使用这些技术来构建一个功能齐全的Todo应用,包括添加、删除、编辑和完成任务等功能。此外,您还将学习如何使用Redux来管理应用程序的状态,以实现更好的可扩展性和可维护性。
项目搭建
首先,我们创建一个新的React项目。您可以使用create-react-app工具来轻松完成此步骤。
npx create-react-app todo-app --template typescript
这将创建一个名为todo-app的项目,并安装必要的依赖项。
接下来,我们需要安装TypeScript和Redux。
npm install --save typescript @types/react @types/react-dom
npm install --save redux react-redux
安装完成后,我们需要在项目中配置TypeScript。在tsconfig.json文件中,将compilerOptions.target设置为ES5,并将module设置为commonjs。
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs"
}
}
最后,我们需要在项目中配置Redux。在src/index.js文件中,导入Redux并创建一个store。
import { createStore } from 'redux';
import { todoReducer } from './reducers/todoReducer';
const store = createStore(todoReducer);
export default store;
使用React Hooks构建组件
React Hooks是React 16.8中引入的一组新特性,它允许我们在函数组件中使用状态和生命周期方法。在我们的Todo应用中,我们将使用Hooks来构建组件。
首先,让我们创建一个TodoItem组件。该组件将负责渲染单个待办事项。
import React, { useState } from 'react';
const TodoItem = ({ todo, onDelete, onToggle }) => {
const [completed, setCompleted] = useState(todo.completed);
const handleToggle = () => {
setCompleted(!completed);
onToggle(todo.id);
};
const handleDelete = () => {
onDelete(todo.id);
};
return (
<li className={completed ? 'completed' : ''}>
<div className="view">
<input
className="toggle"
type="checkbox"
checked={completed}
onChange={handleToggle}
/>
<label>{todo.title}</label>
<button className="destroy" onClick={handleDelete} />
</div>
</li>
);
};
export default TodoItem;
接下来,让我们创建一个TodoList组件。该组件将负责渲染所有待办事项。
import React, { useState } from 'react';
import TodoItem from './TodoItem';
const TodoList = ({ todos, onDelete, onToggle }) => {
return (
<ul className="todo-list">
{todos.map((todo) => (
<TodoItem
key={todo.id}
todo={todo}
onDelete={onDelete}
onToggle={onToggle}
/>
))}
</ul>
);
};
export default TodoList;
最后,让我们创建一个TodoApp组件。该组件将负责渲染整个应用。
import React, { useState } from 'react';
import TodoList from './TodoList';
const TodoApp = () => {
const [todos, setTodos] = useState([
{ id: 1, title: 'Learn TypeScript', completed: false },
{ id: 2, title: 'Learn React Hooks', completed: false },
{ id: 3, title: 'Learn Redux', completed: false }
]);
const handleAddTodo = (title) => {
const newTodo = { id: Date.now(), title, completed: false };
setTodos([...todos, newTodo]);
};
const handleDeleteTodo = (id) => {
const filteredTodos = todos.filter((todo) => todo.id !== id);
setTodos(filteredTodos);
};
const handleToggleTodo = (id) => {
const updatedTodos = todos.map((todo) => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
setTodos(updatedTodos);
};
return (
<div className="todo-app">
<h1>Todo List</h1>
<input
className="new-todo"
placeholder="What needs to be done?"
onKeyPress={(e) => {
if (e.key === 'Enter') {
handleAddTodo(e.target.value);
}
}}
/>
<TodoList
todos={todos}
onDelete={handleDeleteTodo}
onToggle={handleToggleTodo}
/>
</div>
);
};
export default TodoApp;
使用Redux管理状态
现在,让我们使用Redux来管理应用程序的状态。首先,我们需要创建一个todoReducer。该reducer将负责管理与待办事项相关的所有状态。
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
todos: [
{ id: 1, title: 'Learn TypeScript', completed: false },
{ id: 2, title: 'Learn React Hooks', completed: false },
{ id: 3, title: 'Learn Redux', completed: false }
]
};
export const todoSlice = createSlice({
name: 'todo',
initialState,
reducers: {
addTodo: (state, action) => {
state.todos.push(action.payload);
},
deleteTodo: (state, action) => {
state.todos = state.todos.filter((todo) => todo.id !== action.payload);
},
toggleTodo: (state, action) => {
const todo = state.todos.find((todo) => todo.id === action.payload);
todo.completed = !todo.completed;
}
}
});
export const { addTodo, deleteTodo, toggleTodo } = todoSlice.actions;
export default todoSlice.reducer;
接下来,我们需要在store中注册todoReducer。
import { createStore, combineReducers } from 'redux';
import { todoSlice } from './reducers/todoReducer';
const store = createStore(
combineReducers({
todo: todoSlice.reducer
})
);
export default store;
最后,我们需要在组件中使用Redux。
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, deleteTodo, toggleTodo } from '../reducers/todoReducer';
const TodoApp = () => {
const todos = useSelector((state) => state.todo.todos);
const dispatch = useDispatch();
const handleAddTodo = (title) => {
dispatch(addTodo(title));
};
const handleDeleteTodo = (id) => {
dispatch(deleteTodo(id));
};
const handleToggleTodo = (id) => {
dispatch(toggleTodo(id));
};
return (
<div className="todo-app">
<h1>Todo List</h1>
<input
className="new-todo"
placeholder="What needs to be done?"
onKeyPress={(e) => {
if (e.key === 'Enter') {
handleAddTodo(e.target.value);
}
}}
/>
<TodoList
todos={todos}
onDelete={handleDeleteTodo}
onToggle={handleToggleTodo}
/>
</div>
);
};
export default TodoApp;
现在,我们的应用已经能够使用Redux来管理状态了。
总结
本文介绍了如何使用TypeScript、React Hooks和Redux来构建一个完整的Todo应用。我们从项目搭建开始,逐步学习如何使用这些技术来构建一个功能齐全的Todo应用,包括添加、删除、编辑和完成任务等功能。此外,