Adding state management
This step consists in adding a global state management to the application
The core feature of React is to offer components that rerender when a state change.
The state can be the internal state of the component or the state of a parent component (see The Data Flows Down)
onekijs
provides a global state for the application to store the data that any component can access and react to. This global state is based on Redux.
Final result
The result of this step is as follows:
You can now add a product to the cart by clicking on the "Buy" button available on the product details page.
The "checkout" button is now clickable and displays the cart page
- Vite App
- Nextjs App
Adding global state management
onekijs
provides a store to hold the global state. The store is a Redux store and is automatically started by the <App />
/ <NextApp />
component.
onekijs
provides several hooks to update and react on the global state.
In this tutorial, we will use these hooks:
- useGlobalState to react on a data of the global state, but also to update it
- useGlobalProp to only react on a data of the global state
Adding the shopping cart page
This list of products is stored in the global state under the key "cart".
The global state is an immutable javascript object that looks like this:
{
cart: [
{
name: "Phone XL",
price: 799,
description: "A large phone with one of the best screens",
},
{
name: "Phone Standard",
price: 299,
},
];
}
By default, the global state is an empty object when the application starts. In our case, this means that the shopping cart page displays an empty list of products.
If necessary, it's possible to pass an initial state to the <App />
/ <NextApp />
component.
Add a new page to display the list of products the user wants to buy:
- Vite App
- Nextjs App
loading...
loading...
The function withLayout
is a HOC to provide a consistent layout between each pages of a Next.js application. More details here
It's a good practice to use a constant to identify a property in the global state. Indeed, if a refactoring is needed further on, it's easier to find which component uses which property.
export const STATE_CART = 'cart';
- Vite App
- Nextjs App
loading...
loading...
Adding the "Buy" button
Update the product details component to display a button to purchase the product.
- Vite App
- Nextjs App
loading...
loading...
Update the product details page to handle the click on the "Buy" button.
A click on the "Buy" button calls a function that adds the product to the "cart" property of the global state.
As the cart page reacts on this property, the product will automatically appears on it.
- Vite App
- Nextjs App
loading...
The page below uses Static Generation (getStaticProps and getStaticPaths) which is a feature provided by Next.js. That means in production, the page HTML is generated when you run next build
loading...
As mentioned above, the global state is immutable. Therefore, to update the cart, you need to use cart.concat()
to build a new array and not cart.push()
.
onekijs
transparently handles the immutability of the global state. The cart
variable is a standard javascript object that you can manipulate like any other javascript object excepted that it is frozen.
Advanced tip: As the cart
variable is immutable, the <Cart/> component could use React.memo to be more efficient
Updating the navigation
- Vite App
- Nextjs App
loading...
and finally, update the "Checkout" button to navigate to the cart page
loading...
loading...
Next step
Currently, the contents of the cart are only stored in memory (in the global state) and if you refresh the page, the contents are lost.
In the next step, we will add the ability to authenticate a user and then save the cart contents in the cloud.