I am an experienced developer with a rich portfolio of complex projects, who regularly participates in Open Source projects, conferences, and industry events, sharing knowledge and acquiring new skills. My involvement in the developer community and passion for new technologies make me an ideal candidate to attend Web Summit 2024!

Using React Context API to Manage Global State in Your Application

Discover how to efficiently manage your application's global state using React Context API. Follow along as we build a task management app with user assignment capabilities.

In today's post, I will discuss how you can effectively utilize the React Context API to manage the global state of your application. We'll use a simple task management project (to-do list) as an example, which will also allow assigning tasks to different users.

1. Creating the Context

Firstly, we need to create a context that will hold the global state of our application. We'll create a TaskContext context, which will contain the tasks' state and functions to manage them.

// TaskContext.js

import React, { createContext, useState } from 'react';

const TaskContext = createContext();

const TaskProvider = ({ children }) => {
  const [tasks, setTasks] = useState([]);

  const addTask = (task) => {
    setTasks([...tasks, task]);
  };

  const deleteTask = (taskId) => {
    setTasks(tasks.filter(task => task.id !== taskId));
  };

  return (
    <TaskContext.Provider value={{ tasks, addTask, deleteTask }}>
      {children}
    </TaskContext.Provider>
  );
};

export { TaskContext, TaskProvider };

2. Using the Context in Your Application

Next, we can use our TaskContext context in components to access the global state of tasks and functions to manage them.

// TaskList.js

import React, { useContext } from 'react';
import { TaskContext } from './TaskContext';

const TaskList = () => {
  const { tasks, deleteTask } = useContext(TaskContext);

  return (
    <div>
      <h2>Task List:</h2>
      <ul>
        {tasks.map(task => (
          <li key={task.id}>
            {task.title} - Assigned to: {task.user}
            <button onClick={() => deleteTask(task.id)}>Delete</button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default TaskList;

3. Adding New Tasks

To add a new task to our application, we'll also use the TaskContext context.

// AddTaskForm.js

import React, { useContext, useState } from 'react';
import { TaskContext } from './TaskContext';

const AddTaskForm = () => {
  const { addTask } = useContext(TaskContext);
  const [title, setTitle] = useState('');
  const [user, setUser] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    const newTask = {
      id: Math.floor(Math.random() * 1000),
      title,
      user
    };
    addTask(newTask);
    setTitle('');
    setUser('');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="text" 
        placeholder="Task Title" 
        value={title} 
        onChange={(e) => setTitle(e.target.value)} 
        required 
      />
      <input 
        type="text" 
        placeholder="User" 
        value={user} 
        onChange={(e) => setUser(e.target.value)} 
        required 
      />
      <button type="submit">Add Task</button>
    </form>
  );
};

export default AddTaskForm;

4. Implementing the Main Application Component

In the main component of our application (App.js), we'll use TaskProvider as the parent of all components that use TaskContext.

// App.js

import React from 'react';
import { TaskProvider } from './TaskContext';
import TaskList from './TaskList';
import AddTaskForm from './AddTaskForm';

const App = () => {
  return (
    <TaskProvider>
      <div className="App">
        <h1>Task Management Application</h1>
        <AddTaskForm />
        <TaskList />
      </div>
    </TaskProvider>
  );
};

export default App;

Summary

By using React Context API and useState, we can easily manage the global state of our application, which in this case is tasks. Context allows passing data throughout the component tree without the need to pass props manually through multiple levels of components. This is particularly useful in larger applications where state management can become more complex.

I hope this example was helpful! If you have any questions or suggestions, feel free to let me know in the comments below. Thanks for reading!