Passing the subset of the state to a component

Once we get the response from the API, we will show the information in the UI. To do so, we need to get a subset of the state from the store. And how do we do that? Well, we have already discussed that in Chapter 5, React with Redux, using selectors. Now, let's get the selectors to get an authenticated user and show a welcome message on the screen. 

Create a selector file inside app/containers/App/selectors.js. There is a reason why we are keeping the selector file in the App container and not inside the Login container. This is so we can detect whether a user is logged in or not before sending the user to the login page or dashboard. We are going to use the same selector for both the App and the Login container:

import { createSelector } from 'reselect';

const selectGlobal = state => state.get('global');

const makeSelectCurrentUser = () =>
createSelector(
selectGlobal,
globalState =>
globalState.get('currentUser')
? globalState.get('currentUser').toJS()
: {},
);

const makeSelectLogedIn = () =>
createSelector(
selectGlobal,
globalState => !!globalState.getIn(['currentUser', 'id']),
);

const makeSelectLoading = () =>
createSelector(selectGlobal, globalState => globalState.get('loading'));

const makeSelectError = () =>
createSelector(selectGlobal, globalState => globalState.get('error'));

export {
selectGlobal,
makeSelectLogedIn,
makeSelectCurrentUser,
makeSelectLoading,
makeSelectError,
};

Note the following important aspects:

  1. We are using createSelector from reselect. We have already discussed how it works in Chapter 5, React with Redux. Since we are using immutable.js, we get a subset of the state using the get method. For example, in order to get the global state, we need to state const selectGlobal = state => state.get('global'); 
  2. Now, we create different selectors to select the global state, select if a user is logged in or not, select the current user, select if the application is loading or not, and finally select if there are any errors or not. Pretty straightforward. 
  3. Now, if the user is logged in, we need to take the user to the home page. That is how an authentication system should work. So, inside app/containers/Login/index.js, we add mapStateToProps with an appropriate selector function. Now, your Login container should look like this:
export const mapStateToProps = createStructuredSelector({
isLoggedIn: makeSelectLogedIn(),
});

export const mapDispatchToProps = dispatch => ({
onSubmit: e => dispatch(onLoginRequest(e.toJS())),
});

const withConnect = connect(
mapStateToProps,
mapDispatchToProps,
);

const withSaga = injectSaga({ key: 'login', saga });

export default compose(
withSaga,
withConnect,
)(LoginPage);
  1. In addition to this, we need to check whether the user is logged in or not. We can use componentDidMount and componentDidUpdate to achieve that. However, in the recent version of React, these life cycle functions are removed and hooks are introduced. Inside the Login container we have the following life cycle methods: 
componentDidMount() {
if (this.props.isLoggedIn) {
this.props.history.push('/');
}
}

componentDidUpdate() {
if (this.props.isLoggedIn) {
this.props.history.push('/');
}
}

With this done, we should have a complete working login flow. Try to log in with the wrong credentials to see if the errors are being caught. If there is an error, the API should respond like this:

{
"status":401,
"message":"Authentication failed. Invalid user or password.",
"errors":{},
"success":false
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset