DEV Community

Giorgi Parunov
Giorgi Parunov

Posted on

One of the ways to use Context API

As you know a lot of developers replaced redux with react context feature. So I want to show you how I am using it in my products.

We will create a Todo list using context API (based on typescript).

I will use bootstrap for design._
_Image description

Final view of our code.

Let's get started!

At first, we must create our context in the contexts folder.

TodoContext.ts

import { createContext } from "react";

export interface ITodo {
    name: string;
    completed: boolean;
}

interface ITodoContext {
    data: ITodo[];
    updateData: Function;
}

export const TodoContext = createContext<ITodoContext>({
    data: [],
    updateData: (data: ITodo[]) => {
        throw new Error('updateData not implemented')
    }
})
Enter fullscreen mode Exit fullscreen mode

Here we can see that we are creating an interface for todo items, and also for todo context.

My context has two values, the first one is the data that it must contain and the second one is the function that will update the data.

After creating context we must create a provider for it.
We are creating it in the providers folder.

TodoProvider.tsx

import {FC, ReactNode, useState} from "react";
import {ITodo, TodoContext} from "../contexts/TodoContext";

interface ITodoProvider {
    children: ReactNode
}

export const TodoProvider:FC<ITodoProvider> = ({children}) => {

    const [data, setData] = useState<ITodo[]>([]);

    const updateData = (data: ITodo[]) => {
        setData(data);
    }

    return (
        <TodoContext.Provider value={{data, updateData}}>
            {children}
        </TodoContext.Provider>
    )
}
Enter fullscreen mode Exit fullscreen mode

In our todo provider, we will create and append the initial state for todo data. Also, we must create a function for handling data updates and appending it to our state.

Now we can start to use our created context API in our product.

What we must do:

  • Render Todo List.
  • Create Todo Item.
  • Delete Todo Item.

So let's do it step by step

Render Todo List
Idea is to render the table with our todo data.

We will create a TodoList.tsx file in the components folder.

export const TodoList = () => {
  const {data: todoData} = useContext(TodoContext);

  return (
    <div className="container">
      <div className="d-flex justify-content-between" >
        <div className="py-3">
          <h3>Todo List</h3>
        </div>
      </div>
      <table className="table table-striped table-dark">
        <thead>
          <tr>
            <td>Name</td>
            <td width="200">Status</td>
            <td width="150" align="right">Action</td>
          </tr>
        </thead>
        <tbody>
        {
          todoData?.map((item: ITodo, index) => (
            <tr key={`todo-${index}`}>
              <td>{item.name}</td>
              <td>
                {item.completed 
                  ? <span className="badge badge-info">Completed</span> 
                  : <span className="badge badge-secondary">Not Completed</span>
                }
              </td>
            </tr>
          ))
        }
        </tbody>
      </table>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Here you can see that we are using reacts useContext hook for getting our data from context.

const {data: todoData} = useContext(TodoContext);

So we will have always up-to-date data that we are getting from
TodoContext.

Of course, it will be always empty, so we must add create functionality for it.

Lets create a simple form.

<form ref={formRef} className="py-3 d-flex justify-content-between" onSubmit={handleCreate}>
    <input type="text" name="name" className="form-control" />
    <button type="submit" className="btn btn-primary mx-1">Add</button>
</form>
Enter fullscreen mode Exit fullscreen mode

We must create handleCreate function in our component for detecting submitting in form.


const {data: todoData, updateData: updateTodoData} = useContext(TodoContext);

const handleCreate = (event: React.SyntheticEvent) => {
  event.preventDefault();
  const {target} = event as typeof event & {target: {name: { value: string };}}
  const name = target.name.value;
  updateTodoData([
    ...todoData,
    {
      name: name,
      completed: false
    }
  ])
  formRef?.current?.reset();
}
Enter fullscreen mode Exit fullscreen mode

Here you can see that we added updateData which we are taking from our context, and using it as updateTodoData for creating and saving new todo item.

Thats it. Now on submitting form it will create and render new item in our todo list.

By the same logic we can create delete functionality also.

const handleDelete = (name: string) => {
  const payload = todoData.filter(item => item.name !== name)
  updateTodoData(payload);
}
Enter fullscreen mode Exit fullscreen mode

We are taking the name and filtering our array by it.
After it, we are using our updateTodoData function and update our array.

You can check the repository here

And how you are using Context API in your applications?

Top comments (0)