Building an interactive to-do list application: Using React and Redux to achieve technical in-depth combat

This article will introduce how to build an interactive to-do list application using React and Redux framework. We will use the idea of ​​React componentization and Redux's state management to realize the functions of adding, completing and filtering to-do items. Through the practical demonstration of this article, readers will have a deep understanding of the usage and related concepts of React and Redux, and lay a solid foundation for building complex front-end applications.

image.png

Technology stack:

  • React: A popular JavaScript library for building user interfaces.
  • Redux: A predictable state container for managing application state.

Step 1: Project initialization and configuration First, make sure you have Node.js and npm installed. Then, execute the following command on the command line to initialize a new React project:

$ npx create-react-app todo-app

Enter the project directory:

$ cd todo-app

Step 2: Create a task list component Create a folder named components under the src directory, and then create a file named TodoList.js under this folder. Write the following code in TodoList.js:

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { addTodo, toggleTodo, deleteTodo } from '../actions/todoActions';
​
const TodoList = () => {
  const todos = useSelector(state => state.todos);
  const dispatch = useDispatch();
​
  const handleAddTodo = (e) => {
    e.preventDefault();
    const newTodo = {
      id: Date.now(),
      text: e.target.todo.value,
      completed: false
    };
    dispatch(addTodo(newTodo));
    e.target.todo.value = '';
  };
​
  const handleToggleTodo = (id) => {
    dispatch(toggleTodo(id));
  };
​
  const handleDeleteTodo = (id) => {
    dispatch(deleteTodo(id));
  };
​
  return (
    <div>
      <h2>Todo List</h2>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            <input type="checkbox" checked={todo.completed} onChange={() => handleToggleTodo(todo.id)} />
            <span style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>{todo.text}</span>
            <button onClick={() => handleDeleteTodo(todo.id)}>Delete</button>
          </li>
        ))}
      </ul>
      <form onSubmit={handleAddTodo}>
        <input type="text" name="todo" placeholder="Enter a task" required />
        <button type="submit">Add</button>
      </form>
    </div>
  );
};
​
export default TodoList;

In the above code, we define a TodoList component, which is responsible for displaying the task list, adding tasks, completing tasks and deleting tasks. We use the useSelector and useDispatch hook functions provided by React Redux to obtain the state and dispatch actions from the Redux store respectively. In the template, we use the map method to render the list of tasks in a loop, and use the useState hook and event handlers to handle adding, completing, and deleting tasks.

Step 3: Create Redux-related files Create a folder named actions under the src directory, and create a file named todoActions.js under this folder. Write the following code in todoActions.js:

export const addTodo = (todo) => {
  return {
    type: 'ADD_TODO',
    payload: todo
  };
};
​
export const toggleTodo = (id) => {
  return {
    type: 'TOGGLE_TODO',
    payload: id
  };
};
​
export const deleteTodo = (id) => {
  return {
    type: 'DELETE_TODO',
    payload: id
  };
};

In the above code, we define three action creation functions, which are used to add tasks, complete tasks and delete tasks respectively. Each action creation function returns an object containing type and payload attributes, type is used to specify the action type, and payload is used to pass related data.

然后,在src目录下创建一个名为reducers的文件夹,并在该文件夹下创建一个名为todoReducer.js的文件。在todoReducer.js中编写以下代码:

const initialState = {
  todos: []
};
​
const todoReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return {
        ...state,
        todos: [...state.todos, action.payload]
      };
    case 'TOGGLE_TODO':
      return {
        ...state,
        todos: state.todos.map(todo =>
          todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
        )
      };
    case 'DELETE_TODO':
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.payload)
      };
    default:
      return state;
  }
};
​
export default todoReducer;

在上述代码中,我们定义了一个todoReducer函数,它接收当前状态和动作对象作为参数,并根据动作类型对状态进行处理。在不同的情况下,我们返回一个新的状态对象,保持了Redux的不可变性原则。

步骤4:创建根组件 在src目录下的App.js文件中编写以下代码:

import React from 'react';
import TodoList from './components/TodoList';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import todoReducer from './reducers/todoReducer';
​
const store = createStore(todoReducer);
​
const App = () => {
  return (
    <Provider store={store}>
      <div className="App">
        <TodoList />
      </div>
    </Provider>
  );
};
​
export default App;

在上述代码中,我们导入React组件TodoList、Provider组件和createStore函数。然后,创建了一个Redux的store实例,将todoReducer作为参数传入。最后,使用Provider组件将根组件包裹起来,并将store作为props传递给Provider组件。

步骤5:运行应用 在命令行中执行以下命令启动开发服务器:

$ npm start

访问http://localhost:3000/,你将看到待办事项应用的界面。你可以添加任务、完成任务和删除任务。

结论: 本文通过使用React和Redux框架,构建了一个交互式的待办事项应用。我们介绍了React的组件化思想和Redux的状态管理,包括动作创建函数和状态处理函数的编写。通过本文的实战演示,你可以掌握React和Redux的核心概念和使用方法,为构建复杂的前端应用提供了一个强大的工具。

步骤6:添加过滤功能 在src目录下的components文件夹中创建一个名为TodoFilter.js的文件。在TodoFilter.js中编写以下代码:

import React from 'react';
import { useDispatch } from 'react-redux';
import { setFilter } from '../actions/filterActions';
​
const TodoFilter = () => {
  const dispatch = useDispatch();
​
  const handleFilterChange = (e) => {
    dispatch(setFilter(e.target.value));
  };
​
  return (
    <div>
      <h2>Filter:</h2>
      <select onChange={handleFilterChange}>
        <option value="all">All</option>
        <option value="completed">Completed</option>
        <option value="active">Active</option>
      </select>
    </div>
  );
};
​
export default TodoFilter;

在上述代码中,我们定义了一个TodoFilter组件,它负责展示过滤选项和处理过滤选项的变化。我们使用React Redux提供的useDispatch钩子函数来派发设置过滤选项的动作。在模板中,我们使用select元素和onChange事件处理函数来监听过滤选项的变化,并将选中的值派发给Redux的store。

Step 7: Update the root component In the App.js file under the src directory, import the TodoFilter component and add the TodoFilter component in the root component.

import React from 'react';
import TodoList from './components/TodoList';
import TodoFilter from './components/TodoFilter';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import todoReducer from './reducers/todoReducer';
​
const store = createStore(todoReducer);
​
const App = () => {
  return (
    <Provider store={store}>
      <div className="App">
        <TodoFilter />
        <TodoList />
      </div>
    </Provider>
  );
};
​
export default App;

Step 12: Style the application In the App.css file under the src directory, add the following style codes to beautify the appearance of the application:

.App {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin-top: 50px;
}
​
h2 {
  margin-bottom: 10px;
}
​
ul {
  list-style: none;
  padding: 0;
}
​
li {
  margin-bottom: 10px;
}
​
input[type="checkbox"] {
  margin-right: 10px;
}
​
button {
  margin-left: 10px;
}

In the above code, we have applied some basic styles to elements such as the application's container element, title, task list, list items, checkboxes, and buttons. You can adjust the style according to your needs.

Summarize:

This article introduces in detail how to use React and Redux framework to build an interactive to-do list application through a practical project example. From project initialization, component writing, state management to adding filtering functions, we have demonstrated the complete development process step by step. Through this practical project, readers can learn the core concepts and usage methods of React and Redux, which provides a strong foundation for developing other complex front-end applications. I hope this article can be helpful to your front-end development learning and practice!

Guess you like

Origin juejin.im/post/7243383094773153850