React: how to use the useContext hook in combination with the useReducer and firebase for user authentification

Let's get started

Setting up the project

To begin with, you can create a new react application or use your existing one. Feel free to skip this step in case you are not interested in setting up a new project with react and firebase

yarn add firebase
REACT_APP_API_KEY=
REACT_APP_AUTH_DOMAIN=
REACT_APP_DATABASE_URL=
REACT_APP_PROJECT_ID=
REACT_APP_STORAGE_BUCKET=
REACT_APP_MESSAGING_SENDER_ID=
REACT_APP_APP_ID=
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/auth";
import "firebase/storage";

const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DATABASE_URL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
};

firebase.initializeApp(firebaseConfig);

export const auth = firebase.auth();
export const storage = firebase.storage();
export const firestore = firebase.firestore();

The state management

According to the React documentation, the useContext hook:

const authReducer = (state, action) => {
switch (action.type) {
case 'REGISTER':
return {...state, account: action.payload.account, profile: action.payload.profile}
case 'LOGIN':
return {...state, account: action.payload.account, profile: action.payload.profile}
case 'UPDATE_PROFILE':
return {...state, profile: action.payload.profile}
case 'UPDATE_ACCOUNT':
return {...state, account: action.payload.account}
case 'LOGOUT':
return {...state, account: {}, profile: {}}
case 'ERROR':
return {...state, errors: action.payload.errors}
default: {
throw new Error(`Unhandled action type: ${action.type}`)
}
}
}
const initialState = {
account: {},
profile: {},
errors: [],
}
const AuthContext = React.createContext(initialState)
const AuthProvider = ({children}) => {
const [state, dispatch] = React.useReducer(authReducer, initialState)
const value = {state, dispatch}


return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
}

export {AuthContext, AuthProvider}
import React from 'react';
import ReactDOM from 'react-dom';
import {ModalProvider} from "./providers/modalProvider";
import App from "./App";
import {AuthProvider} from "./providers/authProvider";

ReactDOM.render(
<React.StrictMode>
<AuthProvider>
<App/>
</AuthProvider>
</React.StrictMode>,
document.getElementById('root')
);
const {state, dispatch} = React.useContext(AuthContext)
onClick={() => {
dispatch({type: 'LOGOUT'})
}
import React from 'react'

/* REDUCER */
const
initialState = {
account: {},
profile: {},
errors: [],
}

const authReducer = (state, action) => {
switch (action.type) {
case 'REGISTER':
return {...state, account: action.payload.account, profile: action.payload.profile}
case 'LOGIN':
return {...state, account: action.payload.account, profile: action.payload.profile}
case 'UPDATE_PROFILE':
return {...state, profile: action.payload.profile}
case 'UPDATE_ACCOUNT':
return {...state, account: action.payload.account}
case 'LOGOUT':
return {...state, account: {}, profile: {}}
case 'ERROR':
return {...state, errors: action.payload.errors}
default: {
throw new Error(`Unhandled action type: ${action.type}`)
}
}
}

/* COMPONENT */
const
AuthContext = React.createContext(initialState)

const AuthProvider = ({children}) => {
const [state, dispatch] = React.useReducer(authReducer, initialState)
const value = {state, dispatch}

return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
}

export {AuthContext, AuthProvider}

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store