-
Notifications
You must be signed in to change notification settings - Fork 2
Build Your Own State Container
The next step is to examine Redux
. However, before diving straight in, it's
important to understand what Redux
is trying to accomplish. This section
demonstrates a simple state container that mimics the core functionality of
Redux
. It's curious how little code is required to accomplish this.
- Navigate to the
state-container
directory and run the following commands:npm install npm start
Once the app loads, play the `Pirate Tic Tac Toe game to familiarize yourself with the app
Open the
state-container
folder using your favorite editor (again, VIM...) and familiarize yourself with the application
-
The core functionality of
Redux
can be reproduced in 13 lines of code as demonstrated in theStore.js
file.- The entire state in the store is held in the
internalState
private variable. - The store accepts a reducer that maps logic to intents. This is the only
means of mutating the store's state. In
Redux
parlance, an intent in an action. - The subscribe method accepts functions that will execute after every
dispatch event. This is the typical mechanism by which
Redux
informsReact
that is should re-render the application. - The
getState
method simply returns the application state.
// Store.js export const createStore = (reducer, defaultState) => { let internalState = defaultState; let handlers = []; return { dispatch: (intent) => { internalState = reducer(internalState, intent); handlers.forEach(h => h()); }, subscribe: handler => handlers.push(handler), getState: () => internalState, }; };
- The entire state in the store is held in the
-
The
StateContainer.js
file is where the intents for the Pirate Tic Tac Toe application are defined. Each intent accepts a model and returns a new model. The model itself is never actually mutated, it's replaced with a new model.// StateContainer.js const intents = { PLAY: (model, intent) => { ... return {...model, player, winner, gameBoard}; }, RESET_GAME: model => { ... return {...model, gameBoard: emptyBoard, winner: null}; }, };
-
The application must instantiate a single global container to be used everywhere within the application.
// StateContainer.js const update = (model, intent) => { let action = intents[intent.type]; if (!action) return model; return action(model, intent); }; var container = createStore(update, defaultState);
-
Intents are joined with end user action in the view.
// GameSquare.js onClick={() => { StateContainer.dispatch({ type: 'PLAY', row: props.row, square: props.square, }); }}> // ResetGame.js <button onClick={() => StateContainer.dispatch({type: 'RESET_GAME'})}> New Game </button>
What pattern does the Custom State Container adhere to?
- Observer
- State Machine
- Publisher/Subscriber
- Singleton
- Convert the state-container application to a
Redux
application via the: following two steps
- Navigate to the
state-container
directory and run the following command.npm i --save redux
- Change the import at the top of the 'StateContainer.js` file.
- import {createStore} from './Store'; + import {createStore} from 'redux';- Run the application and marvel at your genius.
There are no pros and cons listed in this section because it's not advisable to
build a custom state container. This section is meant to merely convey the
concept about how React
works under the hood.