- Read Tutorial
- Watch Guide Video
In this video we want to make it so that we can set this data into our redux store, so we can actually do stuff with it later on throughout this application. Such as requests, and other stuff, handling those properly.
So I want to do is let's go ahead and import an action here. So before importing it, let's create a file in our actions called types.js, and here we want to export constant and types. So the first one is going to be:
types.js
export const STORE_USER = 'STORE_USER'
I'm not going to go to in depth of how this kind of works, just because we've been over it. I will explain it slightly. So we have this constant STORE_USER
, and we want to use this in our actions and in our reducer because we could just use a string, but it's easier to use a constant like this.
It's a little bit harder actually, but it's better because it's more likely we that we don't run into errors because of what it's called. It's a constant. It can only be worth one thing. Let's go into our auth.js and say:
auth.js
import { STORE_USER } from './types';
Now what we need to do is basically dispatch it after we get a response.
auth.js
export function signUp(fields, success) { console.log(fields); return function(dispatch) { axios.post(`${ROOT_URL}/signUp`, fields) .then(response => { console.log(response); dispatch({ type: STORE_USER, payload: response.data }) success() }) .catch(err => { if(err) { console.log(err) } }) } }
So if you remember response gave us back response, and data was one of those. Data contained what we sent from the server that I built. Alright, I'm going to get rid of the console.log
here, and we'll console.log it in the reducer to make sure it's hitting that reducer.
Let's make sure this is spelled right: response.data
. Alright, let's go to our reducers, and right now we only have form
, but we want to create another. We want to create another one called authReducer
. So let's create a file in our reducers directory, and let's call it authReducer.js
. In here we want to import the actions, so let's say:
authReducer.js
import { STORE_USER } from '../actions/types'; export default function(state = [], action) { switch (action.type) { case STORE_USER: console.log(action.payload); return { ...state, user: action.payload } default: return state; } }
So let's go ahead and use this in our index.js in reducers. We need to import it. I'm going to say:
index.js
import auth from './authReducer';
So it's going to take our function in authReducer.js, and basically call it auth
. Now what we need to do is just put it in our combined reducers call.
index.js
const rootReducer = combineReducers({ form, auth });
Now if we go to our application in the browser and we hit ReduxDevTools
to the left, you're not going to see anything yet. It's just going to say: state form
and auth
. Nothing is going to be in auth
.
When we go to create an account: let's give it a name, a unit, and let's give it a random e-mail. It really doesn't matter what the e-mail is. We will delete all of these from our database possibly later on anyway. Hit create account, and it's printing.
Alright, this is from our sign up form. Let me show you this: so we have e-mail, password, full name, and unit. You'll see it even says: auth.js:11
.
So that occurring in auth.js line 11. So it's happening at the top of our sign up function in auth.js. So get rid of that.
Don't save it though, that's going to reload her application. We don't want to create a billion accounts really. Ok, let's go in here, and you'll see that: (if you did save it, and reload it, you will just have to create another account) this response will be gone, or this print be on, but you'll see this with the token still. This contains a token and a user. That's our payload.
So basically what we want to do is store the user in redux, and then store the token in what we call local storage. So let's go ahead and ignore the token part and keep story keep working on storing the user. Let's go in here and let's go back and save it. Then let's go back to our authReducer.js.
So we know that action.payload
contains a token and the user object. So we really need to say .user
, get rid of the console log, provide a default state, provide a constant, and update our import:
authReducer.js
import { AUTHENTICATE_USER } from '../actions/types'; const INITIAL_STATE = { authenticated: false, user: [] } export default function(state = [], action) { switch (action.type) { case AUTHENTICATE_USER: return { ...state, user: action.payload.user } default: return state; } }
Then we need to go ingo our types.js and change this to:
types.js
export const AUTHENTICATE_USER = 'AUTHENTICATE_USER'
There's one more place that we need to change this, and it's in auth.js. We need to dispatch the type of AUTHENTICATE_USER
and make sure we are importing AUTHENTICATE_USER
.
Now in our authReducer.js we have authenticated and user. So we're storing the user now and let's just fix up the syntax a bit. Let's say:
authReducer.js
import { AUTHENTICATE_USER } from '../actions/types'; const INITIAL_STATE = { authenticated: false, user: [] } export default function(state = [], action) { switch (action.type) { case AUTHENTICATE_USER: const { user } = action.payload; return { ...state, user } default: return state; } }
Now, let's reload our application, and there's two things we want to look at, and the first thing is the initial stage. We want to see this in our dev tools, although we won't until we replace this couple of brackets here with an initial state.
authReducer.js
export default function(state = INITIAL_STATE, action) { switch (action.type) { case AUTHENTICATE_USER: const { user } = action.payload; return { ...state, user } default: return state; } }
Now what we need to do is look for this when we load it up, and then we're not logging anything except for this, and this should basically fill it up. So it's going to say ...state
, so it's going to take everything and put it in there.
Then we're going to overwrite user with user, thenew payload, and the new payload that contains user which were taking out of the payload. Let's go to the application.
Let's pull this to the right a bit so we can see everything. Right now user contains nothing. So let's go ahead and reload our application, because it should contain a default state, and auth which contain authenticated and users.
Let me go back to the code and show you what that is. See authenticated and user.
Back to the dev tools authenticated and user. State->auth->authenticated and user
. Let me go back to the code, and I just really want to hit home with this. To show you what I'm trying to show you, and how this works.
So we have this initial state, and we're kind of go backwards here. See we have authenticated
and user
. We're going backwards. Let's go up to auth which is in index.js. You see we have auth
right here. You can also see we have form
right here.
We have form and auth. Then above this we have state. So you can always think of root reducer as state in this chart, but it's not OK. So that's a little overview of how that works. I'm going to pull this back and I'm going to go back to Chrome and what's actually perform the post request, and see those objects change state.
Let's go ahead and fill it out, and you'll see redux-form tripping out, but that has nothing to do with auth. So don't worry about that. Fill in the data, put in some unit number, a unique e-mail, and a password. Now notice user and authenticated are still empty, but when we create account it pulls in a bunch of data and it fills in our user and authenticated.
It actually gets rid of our form data, and that's because we navigated to /dashboard
, which doesn't have a route yet which means there's no component which means none of our forms are basically on the screen. So we don't have any of that form data. We do have auth
still as user, and it still has authenticated
.
Authenticated
is still false because we used the spread operator, and copied everything over here. So it's false/empty user, and then we overwrite user with our user object from our response from the server.
So we have full name and all that junk. That's how that works. Let's go ahead and commit our code and move on to the next video, where we will store our token or from our payload in the local storage so we can authenticate requests. Let's say git status
, git add .
, and git commit -m "AUTHENTICATE USER reducer"
. I'm going to push to github with git push origin
, and I'll see you in the next video.