You are on page 1of 43

Redux

with React Native and a


Todo App
REDUX
If you don’t know what’s Redux, you can just think of it like a collection of
functions with a component called the Provider that allows you to access and
change your state from any component within the app.
Redux is a State Management Library for projects that have so many state
variables that needs to be accessed from multiple components as well as for
many other reasons you can read about in their official websites. Redux mostly
removes the need to pass state values as props around components (in some
instances components that have components that have components.. so on)
just to get other state values like your App Settings.
The 5 important parts for anyone starting out in learning about Redux should
focus on understanding are these (next slide).
STORE
Store is like a literal storage area, A plastic container with Dividers. You can either
retrieve or update what’s inside of those little boxes inside (don’t mind what’s inside).
The store is the global app state container and its made accessible by the Provider
component from react-redux.
STORE
That’s why in the App.js file which is most top-level component in the App. The code
looks like this:

Notice how the store is given


as a prop, the value of the prop
which is named store as well but…
What is being passed to
the store prop?
STORE
Simply put a store is just(but not really just) a Function that returns an Object or Array
but most of the time an object.
You can change up the code in the snack to be like this:
STORE
So know we know what the store requires, a function that returns an object.
So what’s the object? It’s your global state.
But remember the major rule, you cannot directly modify or make changes
to that object like you can do with a normal Javascript Object because we
want to make its contents easy to determine or determinable (if there’s
such a word).
That fat arrow function we created that to return an empty object is actually
what we’ll use to make changes to the state.
Enter the reducer but for now will go back to the snack.
STORE
So know we know what the store requires, a function that returns an object.
So what’s the object? It’s your global state.
But remember the major rule, you cannot directly modify or make changes
to that object like you can do with a normal Javascript Object because we
want to make its contents easy to determine or determinable (if there’s
such a word).
That fat arrow function we created that to return an empty object is actually
what we’ll use to make changes to the state.
Enter the reducer but for now will go back to the snack.
STORE
Now that we know this let’s explore what’s on the snack. If you would notice the
import store from ‘./redux/store’ when you open the file you see this:

What’s createStore()? The createStore function basically adds some additional


functions like .dispatch() that will allow you to send an action to the reducer but
it still returns your state.
Inside the createStore is the reducer which is what we’ll be talking about next.
REDUCER
The reducer is just a function that returns an object either your entire state
if you’re only using 1 Reducer like in our example or multiple pieces of the
global state (Like the boxes above inside the 1 big container).

What does this function take in as arguments? The reducer function takes
in two things: A State, and an Action. An action is just a JavaScript Object
with two keys:
REDUCER
But let’s talk more about
Actions later, let’s focus
on Reducers.

Here is the Todos


Reducer simplified and
commented, we
purposely changed the
code here compared to
the snack so you could
see a variation in the
implementation.
REDUCER
The reason the documentation calls it a pure function is because we do not
and should not modify the state we return but what we could do is create a
copy of the current state then either exclude(for delete) or include(add or
update) our changes or additions to the state. Also, Asynchronous code are
not allowed in a reducer.

The point is reducer functions either return the original state or a brand new
state whose values are copied from the original state.
REDUCER
Going back to this where we see rootReducer
REDUCER
What is the rootReducer? We need to go to the actual file itself on the snack, there is
another folder on redux named reducers.
The index.js file contains a single most important function which is combineReducers({ todos
}).
Just to be clear rootReducer is actually combineReducers({ todos }). The reason why we hid it
away is because we just want to make the code more manageable and nice to look at.
REDUCER
combineReducers() from the redux library simply allows you to combine multiple reducer functions which
We have said holds pieces of your global state. For example, besides todos_reducer, when the app grows
larger it might have a user account portion of the state that will need its own reducer.
So why did we encapsulate our todos reducer inside a combineReducers() function when we only had
one reducer? It’s to prepare our app to be scaled to accommodate multiple reducers if it ever does.
You can just think of combineReducers as one big reducer function composed of many smaller reducer
functions.
REDUCER
Now, going to our todos reducer we’re going to find that it only varies a little
bit from what we already made above:
REDUCER
So what does the global state look like if we have added some todos?
REDUCER
This is the reason why the global store should return an object, because
when you eventually have more than one reducer, eventually every reducer
will have a key in the global state and its value is the initialState you defined
in that reducer file.

So now we know the store and reducer, we can finally shed some light on
Actions which we’ve already seen here on Reducer.
ACTIONS
Actions as we said before is nothing more than another Javascript object but
it has two keys (as a standardized way only, it’s not strict) which are type and
payload.
ACTIONS
From our snack example on the actions.js file here, you can see that this is
exactly what it does, it returns an object:
ACTIONS
In fact, if we didn’t need parameters or inputs from the user, we would have
just simply written the addTodo action as:
ACTIONS
What is special about Actions is its purpose.
Actions dictate what code should the reducer execute assuming that it knows
that action (remember the switch statement?). That’s the purpose of the
action.type and action.payload. The action.payload is the actual data you
want to store in the state or use for updating or deleting data in the state.
But the main point about Actions is that it isn’t capable of doing anything it’s
only a message to be sent to the reducer so that the reducer knows what to
do with your state.
So then, How does the message reach the Reducer(s)?
The dispatch function that we got from createStore() remember?
DISPATCH
If you’ll visit the Redux documentation you’ll see a demo of how dispatch is
used in their counter app.

This is how the Action reaches the Reducer because remember the store
creation?
DISPATCH
In short, the dispatch is a function from your created store that is used to
send your action to the reducer(s) and the reducer(s) will determine what to
do using their switch case comparison with action.type.

But, you may be wondering because our snack.expo app does not have this
dispatch()? So where is it?

There’s a little magic the react-redux library did for us to avoid using the
dispatch() as well as other functions *unless we explicitly need to* and that’s
through the connect() higher-ordered function.
CONNECT
connect() which is imported from react-redux is the last important part of our
Redux for beginners journey because this is the function that allows you to
perform dispatch() in your component but also retrieve any redux state
variables you want to access for your component.

We made this todoapp a one liner so that you can quickly go to it on


screens/TodoApp. Observe these imports on the snack.
CONNECT
Then scroll to the bottom and find the export default code:
CONNECT
It looks weird but essentially the main syntax to use the connect is:

But what’s the magic that allows this component to access our todo list for
display? and how does this component allow adding and deleting a todo?
The magic is definitely not black magic but the connect() does a lot of things
for you already so you don’t have to.
connect() should be passed with two objects, the first one is the
mapStateToPropsobject (again just a standardized name) and
mapDispatchToProps object.
CONNECT
The mapStateToProps object if you follow this code which is actually based
on the generic redux syntax. This code allows you to retrieve the redux state
through the state parameter and assign a key to that redux state variable. In
our case we needed to return the todos_list so we could display it to the
screen.

**Important: Remember that you need to retrieve them as prop objects


(either destructured or as props.todos_list)

In mapDispatchToProps, you will need to add the actions to that object and
they will automatically be wrapped around in the dispatch() function like this
dispatch(addTodo).
CONNECT
But we could have also implemented it this way just for the sake of having a
choice.
CONNECT
In our case for this app at least, this method was unnecessary. So we used
the more convenient one in our snack.
**Important: Remember that you still need to retrieve them as prop objects
(either destructured or as props.addTodo)
CONNECT
Simply calling the mapped action like addTodo(), allowed me to quickly invoke
the dispatch function by calling the addTodo function that returns our Action
object which gets interpreted(like the example below) then sent to the
rootReducer.

There are many ways that the connect() function can be confusing as well as
the mapStateToProps and mapDispatchToProps object but this is one
approach we could suggest you to try.
PROJECT STRUCTURE
COMPONENTS FOLDER
COMPONENTS FOLDER
REDUX/REDUCERS FOLDER
REDUX/REDUCERS FOLDER
REDUX FOLDER
REDUX FOLDER
REDUX FOLDER
SCREENS FOLDER
SCREENS FOLDER
SCREENS FOLDER
SCREENS FOLDER
APP.JS

You might also like