🚀 Redux Todo List Refactor: Presentational & Container Components - SkillBakery Studios

Breaking

Post Top Ad

Post Top Ad

Monday, July 20, 2026

🚀 Redux Todo List Refactor: Presentational & Container Components

🚀 Redux Todo List Refactor: Presentational & Container Components

Screenshot from the tutorial
Screenshot from the tutorial

Refactoring a Redux Todo List: Presentational and Container Components

In the world of React development, maintaining a clean and manageable codebase is crucial for both scalability and maintainability. One effective way to achieve this is by separating components into presentational and container components. In this blog post, we’ll explore how to refactor a Redux Todo List application by implementing this separation.

Understanding Presentational and Container Components

Before diving into the refactoring process, let's clarify the concepts of presentational and container components:

  • Presentational Components: These components are primarily focused on how things look. They receive data and callbacks exclusively via props, and they don’t manage their own state (except for UI state). Presentational components are typically stateless functional components.

  • Container Components: These components are concerned with how things work. They handle fetching data, managing state, and passing data down to presentational components. Container components are often class components or stateful functional components that utilize hooks.

This separation of concerns enhances the reusability of presentational components and simplifies testing.

Setting Up the Project

If you’re starting from scratch, ensure you have a basic Redux Todo List setup. Your project should include:

  • React
  • Redux
  • Redux Thunk (for async actions)

If you haven't already set up your project, you can use Create React App with Redux and Thunk.

npx create-react-app redux-todo-list
cd redux-todo-list
npm install redux react-redux redux-thunk

Initial Project Structure

A typical folder structure for your Todo List might look like this:

/src
  /components
    TodoList.js
    TodoItem.js
  /containers
    TodoListContainer.js
  /redux
    actions.js
    reducers.js
    store.js

Step 1: Create Presentational Components

TodoItem.js

First, we’ll create the TodoItem component, which is a presentational component that displays a single todo item.

// src/components/TodoItem.js
import React from 'react';

const TodoItem = ({ todo, onToggle }) => {
  return (
    <li 
      onClick={onToggle} 
      style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
    >
      {todo.text}
    </li>
  );
};

export default TodoItem;

TodoList.js

Next, we’ll create the TodoList component, which will render a list of TodoItem components.

// src/components/TodoList.js
import React from 'react';
import TodoItem from './TodoItem';

const TodoList = ({ todos, onToggleTodo }) => {
  return (
    <ul>
      {todos.map(todo => (
        <TodoItem 
          key={todo.id} 
          todo={todo} 
          onToggle={() => onToggleTodo(todo.id)} 
        />
      ))}
    </ul>
  );
};

export default TodoList;

Step 2: Create Container Component

TodoListContainer.js

Now that we have our presentational components, we need to create the container component that connects the Redux store to our presentational components.

// src/containers/TodoListContainer.js
import React from 'react';
import { connect } from 'react-redux';
import TodoList from '../components/TodoList';
import { toggleTodo } from '../redux/actions';

const TodoListContainer = ({ todos, toggleTodo }) => {
  return <TodoList todos={todos} onToggleTodo={toggleTodo} />;
};

const mapStateToProps = (state) => ({
  todos: state.todos,
});

const mapDispatchToProps = {
  toggleTodo,
};

export default connect(mapStateToProps, mapDispatchToProps)(TodoListContainer);

Step 3: Update the Redux Logic

actions.js

Make sure your actions are set up correctly to handle toggling a todo item.

// src/redux/actions.js
export const TOGGLE_TODO = 'TOGGLE_TODO';

export const toggleTodo = (id) => ({
  type: TOGGLE_TODO,
  payload: id,
});

reducers.js

Ensure your reducer handles the toggle action appropriately.

// src/redux/reducers.js
import { TOGGLE_TODO } from './actions';

const initialState = {
  todos: [
    { id: 1, text: 'Learn React', completed: false },
    { id: 2, text: 'Learn Redux', completed: false },
  ],
};

const todoReducer = (state = initialState, action) => {
  switch (action.type) {
    case TOGGLE_TODO:
      return {
        ...state,
        todos: state.todos.map(todo => 
          todo.id === action.payload ? { ...todo, completed: !todo.completed } : todo
        ),
      };
    default:
      return state;
  }
};

export default todoReducer;

Step 4: Connecting Everything in App.js

Finally, connect everything in your App.js.

// src/App.js
import React from 'react';
import { Provider } from 'react-redux';
import store from './redux/store';
import TodoListContainer from './containers/TodoListContainer';

const App = () => {
  return (
    <Provider store={store}>
      <div>
        <h1>Todo List</h1>
        <TodoListContainer />
      </div>
    </Provider>
  );
};

export default App;

Conclusion

Congratulations! You’ve successfully refactored your Redux Todo List application by separating presentational and container components. This approach not only cleans up your code but also enhances the reusability and testability of your components.

By keeping your business logic in container components and your UI logic in presentational components, you can ensure that your application remains scalable and maintainable as it grows.

Feel free to explore further by adding more features, such as filtering todos or implementing a form to add new todos. Happy coding!

Another screenshot from the tutorial
Another view from the tutorial

Connect with SkillBakery Studios

Explore more tutorials, tools, and resources:

Posted by SkillBakery Studios

No comments:

Post a Comment

Post Top Ad