Hello World "Redux"
Last updated
Last updated
Redux — An open source predictable state container
State Tree — A plain JavaScript object which contains whole application state
Three ways to interact with a state (the only ways): Store — A single unit which contains state tree & methods to interact with the state tree Actions — Plan Javascript objects to describe the action taking place Reducers — Pure Javascript functions to take current state and an action to return a new state
Redux is a (predictable) state container for our application, and the state tree is the minimum representation of our application state at any given time.
There is only one state tree that holds the state for the whole application. This means there’s a single source of truth for our data/state.
The state tree lives within the application store. More on this later.
The state tree is read only, meaning we cannot modify or write to it directly. The only way to change it is by dispatching actions.
An action is a plain JavaScript object that describes in a minimal way whatneeds to get updated in the application state. Actions are a way to trigger state mutations: they describe what should change, albeit having no idea how to make that change.
Whether it is initiated by a network request or by user interaction via the UI layer, any data that gets into the Redux store gets there through an action. This means an action can be trigged in response to some user interaction (e.g.: click on a button) but also by the completion or failure of some asynchronous operation, such as a network call.
Actions are identified by a string called action type. This identifier is mandatory, and naturally it’s required to be unique. Action types are strings because they need to be serialisable.
Actions can optionally carry some sort of payload or data required by the corresponding reducer to successfully mutate the state.
By the way, this particular example follows the Flux Standard Actionpattern. This is of course optional but I found it to be a nice way to describe your actions keeping them consistent throughout the application.
Reducers are pure functions which describe state mutations. Unlike actions, reducers do know how to have things changed in the application state, they do know the implementation details for those changes.
The signature for a reducer function is as follows:
where state
is the current application state, action
is the action object which has triggered the state mutation (containing an action type and any relevant payload) and nextState
is the resulting computed state of the app which can be derived from the other two arguments.
The store is the glue that holds all of the Redux building blocks together: the state tree, the action dispatcher and the application reducers. And as such, there can only be a single instance of the store in a Redux app.
Once instantiated, the store
exposes three important methods:
store.getState()
The store holds the state object (aka: state tree). This getState
method retrieves and returns the current state of the Redux store (that is, the current state tree). If we haven't triggered any action yet, getState
will return the initial state of our application.
store.dispatch(action)
The application store allows us to trigger actions in order to have the state of our application changed by exposing a dispatch
method. We only need to pass in a valid action object to it, and the store will take care of the rest.
store.subscribe(callback)
The store also keeps track of all of those who have subscribed to changes in the state tree. The subscribe
method allows us to register a callback that will be run any time an action is dispatched causing the state tree to update. In Reactland (or any other declarative UI library) we can leverage this to trigger a re-render of our view layer.
Note that the subscribe
method returns an unsubscribe
function we can call later on to have ourselves removed from the list of listeners. Calling this unsubscribe
function means we will no longer be notified when something changes in the state tree (i.e.: we stop observing the Redux store).
Only those components that need to be aware of state changes should subscribe to the store, and that’s why we usually make a distinction between presentational and container components. More on this later.