Lab - Add a Redux Slice
Introduction
In this exercise, we’ll practice the use of Redux state in the Buyer Portal. The state we’ll be adding and testing with won’t be useful just yet, but we’ll make use of it in a future exercise.
In this lab, you will:
- Create a custom Redux slice to store global state
- Test setting and retrieving a state value
Setup
This exercise continues where you left off previously. Make sure the dev server is started in your Buyer Portal project:
If you need a fresh start, you can follow the instructions below to set up a new project complete with previous exercise code.
- Copy the project with the appropriate tag.
- Install dependencies.
- Run the dev server.
Remember!
Script Manager in your store control panel must contain appropriate header/footer scripts to load the Buyer Portal from your local environment on the appropriate port.
Revisit the initial setup lab for full details on setting up your environment.
Exercise Reference Copy
If it’s helpful to compare your own code as you go, you can clone or download the completed version of this labs as a reference.
Global State - The CRM Token
In a future exercise, we’ll be simulating fetching support case data from an external CRM. What we’ll ultimately need in this scenario is an authentication token for that separate API, which is appropriate to store globally in the user’s session state, just like the B2B GraphQL token.
In these steps, we’ll set up a custom Redux slice to store this value, as well as test the appropriate entry points for setting it when the application is initialized and retrieving it in the right component.
Step 1: Create a Slice and Hook
Remember, all file paths referenced in these exercises are relative to apps/storefront/src in your Buyer Portal project.
- Open
store/slices/crm.tsand add the appropriate interfaces and slice definition.
Our slice is very simple, containing only a single string value: crmToken.
- Add exports of the slice’s actions, selectors, and reducer.
Breaking Down the Redux Slice
The code we’ve put in place is doing a few things:
- Slice initialization:
createSliceis used to create our unique slice with:- An initial state (containing an empty token value).
- Reducer functions. We have only one, accepting a payload with a new token value and returning a new state.
- Selector functions. Again, we have only
selectCrmToken, used to retrieve the current state value.
- Exports: The file exports important objects that outside code will need in order to manage the slice’s state. Notice that each of these values is found on a property of the slice that was initialized.
- Actions: Functions that can be dispatched to update the slice’s state.
- Selectors: The same selector functions defined in the slice initialization.
- The reducer: A single reducer from the slice contains all the individual reducers, and this in turn will be combined with the reducers of the app’s other slices.
- Persistence: The
redux-persistlibrary is used in the reducer export to persist this slice’s state to the browser’s session storage.
Immutable State
Recall that global state must be immutable, meaning that the state value cannot be changed directly. The syntax in the setCrmToken reducer appears to be doing just that, but this is part of what Redux does under the hood. Redux handles cloning a brand new state object with the new value, allowing us to use a more straightforward syntax in the reducer.
Including the Slice in the Store
Now we need to update a couple of global files to include our new slice with the rest of the app’s slices.
- Open
store/index.tsand add an export for thecrmslice. This will allow any code to import the slice’s actions and selectors directly from@/store.
- Open
store/reducer.tsand addcrmto thecombineReducerscall.
Set Up a Hook
We can use our slice’s selector anywhere in our code, along with the useAppSelector hook from @/store, to retrieve the current value.
We’re going to take this a step further by encapsulating this in our own unique hook. Our code will then be able to use this hook without concerning itself with the details of how the state is retrieved.
- Open
shared/service/crm-bff/useCrmToken.tsand implement the hook.
Step 2: Get and Set the State Value
The details of fetching the CRM token will be handled in a future exercise, but for now we’ll use a static value in the appropriate entry points for setting and retrieving the state.
- Open
App.tsx. This is the central entry point for the application and where we will ultimately initialize the CRM token. - Add an import of the appropriate action.
- Just before the
return, add a React side effect to set the test value.
Notice we’re using storeDispatch, the global store dispatch function, along with our unique action.
- Open
pages/Overview/components/RecentOrders.tsx. This is the component where we’ll eventually be using the token. - Add the hook call and a side effect to log the token value.
You should be able to observe the functionality with your browser developer tools, with the Overview page open:
- View your console to see the test value being logged.
- The persistence of the value should also be evident in the browser’s session storage. Look for the key “persist:crm”.