How to set a cookie in React Js

Last updated : Jul 30, 2023 12:00 AM

The easiest and fastest way to use cookies in React Js is to use Javascript's document.cookie property. Additional dependencies are available to support cookies in React Js, which can then contribute to the increased bundle size. The npm package react-cookie is one of them.

I have a simple form with several input elements in the below example. As you can see, I update the state variable formData with the latest keyboard inputs to keep the form state up to date.

Figure 1: React Js Set Cookies
Figure 1: React Js Set Cookies
const setFormDataCookie = (e: ChangeEvent) => {
  const {name, value} = e.target
  setFormData((oldData) => {
    return {...oldData, [name] : value}
  })
}

When I click the Save to cookie button, my form data is written to a cookie named formCookie. So my data is saved on the disk.

const saveToCookie = () => {
  document.cookie = `${COOKIE_NAME}=${JSON.stringify(formData)}`
}

How to save an Object into a cookie?

We can only save String values in a cookie. If I want to persist an Object to a cookie, first, I must serialize the object to a string. JSON.stringify flattens my Javascript object into a string value. Therefore, I can use JSON.stringify to save a Javascript object in a cookie.

If I refresh the page, I will lose all the data I typed into the form. But my data is already saved on the disk. The Read cookie button reads the saved cookie on the disk and re-populates the form state with the information I entered.

const readCookie = () => {
  const cookies = document.cookie.split(';')
  let formCookie: string = "";
  cookies.forEach((cookie) => {
    if(cookie.startsWith(COOKIE_NAME)){
       formCookie = cookie.replace(`${COOKIE_NAME}=`,"");
    }
  })
  setFormData(JSON.parse(formCookie))
}

Here is the complete code example that covers the above steps.

import { ChangeEvent, useState } from "react";

interface Data {
  name?: string
  website?: string
  email?: string
  country?: string
}

export const UsersDetails = () =>{
const [formData, setFormData] = useState<Data>()
const COOKIE_NAME = "formCookie"

const setFormDataCookie = (e: ChangeEvent<HTMLInputElement>) => {
  const {name, value} = e.target
  setFormData((oldData) => {
    return {...oldData, [name] : value}
  })
}

const saveToCookie = () => {
  document.cookie = `${COOKIE_NAME}=${JSON.stringify(formData)}`
}

const readCookie = () => {
  const cookies = document.cookie.split(';')
  let formCookie: string = "";
  cookies.forEach((cookie) => {
    if(cookie.startsWith(COOKIE_NAME)){
       formCookie = cookie.replace(`${COOKIE_NAME}=`,"");
    }
  })
  setFormData(JSON.parse(formCookie))
}

return(
  <>
  <div>
    <div>Name : <input name="name" value={formData?.name} onChange={setFormDataCookie}/></div>
    <div>Email : <input name="email" value={formData?.email} onChange={setFormDataCookie}/></div>
    <div>Website : <input name="website" value={formData?.website} onChange={setFormDataCookie}/></div>
    <div>Country : <input name="country" value={formData?.country} onChange={setFormDataCookie}/></div>
    <div><button onClick={saveToCookie}>Save to cookie</button>
    <button onClick={readCookie}>Read cookie</button></div>
  </div>
  </>
)
}

Custom hook to set and read cookies

The above code is suitable for single usage. But reusability is a critical concept in designing components. Therefore, I want to move my cookie code into a custom hook, so I can use that functionality in any React component I want.

export const useCookies = (): Function[] => {

  const saveToCookie = (cookieName: string, cookieValue: string | Object): void => {
      document.cookie = `${cookieName}=${JSON.stringify(cookieValue)}`
  }
      
  const readCookie = (cookieName: string, cookieValue: string): string => {
    const cookies = document.cookie.split(';')
    let formCookie: string = "";
        cookies.forEach((cookie) => {
          if(cookie.startsWith(`${cookieName}=`)){
             formCookie = cookie.replace(`${cookieName}=`,"");
          }
        })
        return formCookie
    }
    return [saveToCookie, readCookie]
}

The usage of my new custom hook is simple. I have imported the custom hook in the component and called its methods to set and read cookie data.

import { ChangeEvent, useState } from "react";
import { useCookies } from "./useCookies";

interface Data {
  name?: string
  website?: string
  email?: string
  country?: string
}

export const UsersDetails = () =>{
const [data, setData] = useState<Data>()
const [saveToCookie, readCookie] = useCookies()
const COOKIE_NAME = "formCookie"

const setFormData = (e: ChangeEvent<HTMLInputElement>) => {
  const {name, value} = e.target
  setData((oldData) => {
    return {...oldData, [name] : value}
  })
}

const saveFormToCookie = () => {
  saveToCookie(COOKIE_NAME, data)
}

const populateFormFromCookie = () => {
  console.log(readCookie(COOKIE_NAME))
  setData(JSON.parse(readCookie(COOKIE_NAME)))
}

return(
  <>
  <div>
    <div>Name : <input name="name" value={data?.name} onChange={setFormData}/></div>
    <div>Email : <input name="email" value={data?.email} onChange={setFormData}/></div>
    <div>Website : <input name="website" value={data?.website} onChange={setFormData}/></div>
    <div>Country : <input name="country" value={data?.country} onChange={setFormData}/></div>
    <div><button onClick={saveFormToCookie}>Save to cookie</button>
    <button onClick={populateFormFromCookie}>Read cookie</button></div>
  </div>
  </>
)
}
Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...