Redux
Intro to Redux
Redux is a Predictable State Container for JavaScript Apps, its not just for React. In order to utilize it with React we utilize both the Redux library and the React-Redux library. Now below is an example of the most bare bones react app using Redux and React-Redux I could create. It has a single piece of state managed by Redux which is just a string saying either "yes" or "no" changed by clicking one of two buttons. I've kept the logic as simple as possible so there's minimal clutter and we can more easily track whats happening Redux and React-Redux. We will review each of the four files that makes up example individually, but if you would like to see the app as a whole and keep it on your machine for future reference you can download it from my Github here.Basic Redux App Github
Press the Buttons Below To Sign In or Sign Out
Are you signed in?: no
index.js
The first file we’re going to look at is the root index.js. The first thing to note is the import statementsimport { createStore } from "redux";
import { Provider } from "react-redux";
import reducers from "./reducers";
The Reduxstore
is created by using thecreateStore
function and passing your reducer as an argument. TheProvider
component is wrapped around our App component so that any components within our app will have access to thestore
which we pass to theProvider
component as a prop.
actions.js
The actions.js file contains our Redux actions. Each action is a plain JavaScript object that has a type field. From theRedux Documentation"You can think of an action as an event that describes something that happened in the application."In our case we have two actionssignIn
andsignOut
with their respective types"SIGN_IN"
and"SIGN_OUT"
.
reducers.js
The reducers.js file is where the state is actually changed. First theINITIAL_STATE
is declared with a special all caps syntax and the isSignedInstate
is set to the string "no". Now we export default an anonymous function that takes two arguments.state = INITIAL_STATE
and ouraction
object. We then use a switch statement to switch between the two cases we described in our actions file"SIGN_IN"
and"SIGN_OUT"
. Now Redux has a rule that you cannot modify the existing state. Instead, they must make immutable updates, by copying the existingstate
and making changes to the copied values. One of the easiest ways to do this is to use the Spread Operator, aka the three dots in front...state
. The Spread Operator makes a copy of the original state so we can make changes to the new state object it has created. In our case we simply update the string to say "yes" for"SIGN_IN"
and "no" for"SIGN_OUT"
. We then set the default case to return thestate
unchanged.
App.js
Now our App.js file is where we see all these pieces come together.import { connect } from "react-redux"
import { signIn, signOut } from "./actions";
So lets break down each piece in the order they appear. First we have two event handler functions that call our actionssignIn
andsignOut
. Those two functions are assigned to two onClick events for our Sign In and Sign Out buttons. Then we have an h3 tag displaying{this.props.isSignedIn}
. Now this may seem strange because we have been talking about state this whole time. The reason we call{this.props.isSignedIn}
instead of{this.state.isSignedIn}
is because of the function below.mapStateToProps
takes in the entire store state
and is used to select the part of the data from the store that our connected component needs. It is called every time the store state changes. In our case our store only has one piece of state,isSignedIn
. SomapStateToProps
assignsstate.isSignedIn
to the propisSignedIn
which is available in our App component as{this.props.isSignedIn}
. The final piece is theconnect()
function which we get from React-Reduxexport default connect(mapStateToProps, { signIn, signOut })(App);
This function takes two argumentsmapStateToProps
and the actions you will be using in this component, in our casesignIn
andsignOut
. By passing our actions toconnect()
they will automatically be dispatched to the store, which is the redux way of saying the store will be updated when their called. AKAisSignedIn
will update in the store when they are called. Which leads me to the second benefit of connect()
, by passing our actions to it our component receives them as props. This is why we can call them in the way we didthis.props.signIn()
andthis.props.signOut()
. Lastly we wrap our App
component so it will still be exported as it normally would be but with the added logic coming from Redux and React-Redux.