Persisting Data Using Cookies in React Apps
Tags: react, javascript, tutorial, development
Published: 2021-01-06 03:09:36

When trying to persist data in React apps, there are generally two ways to go: localStorage or cookies. You will find a lot of information and debate about localStorage vs cookies. You will generally see posts concluding that you should use localStorage. That's not this post.

This post will walk you through the use of cookies, via react-cookies. 

## Why Cookies
Initially when building my current project (social media marketing assistant), I decided to use cookies to persist logins because I've already used localStorage in a React app, and I wanted to learn something new!

After some further research, I also decided it was the way to go because I could persist even with browser refreshes and across sessions. I could also give the cookie an expiration date. Also, MDN told me it was okay:

> Cookies are mainly used for three purposes:
>
> **Session management**
> Logins, shopping carts, game scores, or anything else the server should remember

Good enough for me!

### Step 1: Install react-cookie
In your application, install the react-cookie package:
```
npm install react-cookie
```

### Step 2: Wrap with CookiesProvider
You're going to wrap your top-level component in a CookiesProvider component. 

```
import React from 'react'
import ReactDOM, {render} from 'react-dom'
import App from '../components/App'



document.addEventListener("DOMContentLoaded", () => {
  render(
    <CookiesProvider>
        <App />
    </CookiesProvider>,
    document.body.appendChild(document.createElement("div"))
  );
});
```
If you already have it wrapped in a Provider component, courtesy of react-redux, just add it like so:
```
import React from 'react'
import ReactDOM, {render} from 'react-dom'
import PropTypes from 'prop-types'
import App from '../components/App'
import { createStore, applyMiddleware, compose } from 'redux'
import { Provider } from 'react-redux';
import thunk from 'redux-thunk'
import rootReducer from '../reducers/rootReducer'
import { CookiesProvider } from 'react-cookie';


const store = createStore(rootReducer, compose(applyMiddleware(thunk)))
document.addEventListener("DOMContentLoaded", () => {
  render(
    <CookiesProvider>
      <Provider store={store}>
        <App />
      </Provider>
    </CookiesProvider>,
    document.body.appendChild(document.createElement("div"))
  );
});
```

### SetCookie 
React-cookie has some handy-dandy hooks that you can use to set, get and remove cookies. No matter which hook you'll be using, make sure you import useCookies as well as define cookies and your hook of choice.

For example, if I want to set a user cookie based on the currentUser store variable I would do something like this:

```
import React, {useEffect} from "react";
import { BrowserRouter as Router, Route, Switch, Redirect } from "react-router-dom";
import Login from '../components/Login'
import Home from '../components/Home'
import Signup from '../components/Signup'
import {useSelector, useDispatch} from 'react-redux'
import { useCookies } from 'react-cookie';
import {getCurrentUser } from "../actions/userActions";


function Routes() {
  const loggedInUser = useSelector(state => state.currentUser)
  const [cookies, setCookie] = useCookies(['user']);
  const dispatch = useDispatch()
  useEffect(() => {
    if(loggedInUser && cookies["user"] == "undefined") {
      console.log(loggedInUser.id.to_s)
      setCookie('user', loggedInUser.id, {path: '/'})
    } else if (!loggedInUser && cookies["user"] != "undefined"){
      dispatch(getCurrentUser(cookies["user"]))

    }
  })
 
    return (
      <>
      <Router>
        <Switch>
          <Route path="/" exact component={Home}/>
          <Route exact path='/login' >
            {loggedInUser ? <Redirect to="/" /> : <Login />}
          </Route>
          <Route exact path='/signup' >
            {loggedInUser ? <Redirect to="/" /> : <Signup  />}
          </Route>
         
        </Switch>
      </Router>
      </>
    )
}


export default Routes
```

Notice the imports: `import { useCookies } from 'react-cookie';`

The variable declarations: `const [cookies, setCookie] = useCookies(['user']);`
Here, we're connect the variables with a cookie 'user'.

Notice the setting of the cookie: `setCookie('user', loggedInUser.id, {path: '/'})`
This line of code is setting the cookie user with the value of loggedInUser.id, and making it available throughout the app.

You can do something similar to remove cookies:

```
import React from 'react'
import {Link} from 'react-router-dom'
import {useSelector, useDispatch} from 'react-redux'
import {logOut} from '../actions/userActions'
import { useCookies } from 'react-cookie'
import { useHistory } from 'react-router-dom'

function App(){
    const loggedInUser = useSelector(state => state.currentUser)
    const dispatch = useDispatch()
    const history = useHistory()
    const [cookies, removeCookie] = useCookies(['user'])
    const token = document.querySelector('meta[name="csrf-token"]').content;
    const logout = (e) => {
        e.preventDefault()
        removeCookie('user')
        dispatch(logOut(token))
    }
    return(
        <div className="main">
            <h1>Home</h1>
            <ul>
            {!loggedInUser ? <><li><Link to="/login">Login</Link> or </li> <Link to="/signup">Signup</Link> </> :  <><li><form id="logout-form" onSubmit={logout}><input type="submit" value="Log Out"  /></form></li></>}
                
               
                
            </ul>
        </div>
    )
}

export default App
```

It's really that easy to get started!