Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check login status with React-Redux?

I just learned how react-redux works. I currently have login, but I am not sure how to check if the user has logged in or not.

I created a backend with flask and used axios in the fronted to POST a request.

After I login, it just gives me a success status.

Now I want to apply this globally so that the navbar shows the username and can access its own page.

How can I use react-redux to check if the user has logged in?

What kind of action is needed and how do I have to create it?

like image 878
Dawn17 Avatar asked Jun 17 '18 20:06

Dawn17


2 Answers

This is up to your authentication logic but simply, you will create an action for login, then change your state according to this action. For example you can have an auth state in your store, then you can hold user and auth information there. After a successful login, your reducer handles the state change.

Wherever you need login info, you can check via auth state and render your components according to this. Of course either this component needs to be connected to your store or get some props from a container component which is connected to store. Also if you use React Router, you can have public or private routes depending on your auth state.

I have an example sandbox here: https://codesandbox.io/s/yk519xy7px

Here is a very simple code fragments from my example for this logic:

action creator

const userLogin = username => ({
  type: types.AUTH_LOGIN,
  username,
});

// mimicking an async API login endpoing
const fakeLoginRequest = username =>
  new Promise((resolve, reject) =>
    setTimeout(() => {
      username === "foo" ? resolve(username) : reject("No such user");
    }, 1000),
  );

// handling async login 
export const doLogin = username => async dispatch => {
  // incrementProgress is responsible for progress status.
  // Firing a spinner while fetching login info.
  dispatch(incrementProgress());
  try {
    const userResponse = await fakeLoginRequest(username);
    dispatch(userLogin(userResponse));
    // if successfull change our route to "dashboard"
    history.push("/dashboard");
  } catch (error) {
    handleError(error);
  } finally {
    dispatch(decrementProgress());
  }
};

Reducer

const initialState = {
  username: "",
  isLoggedIn: false
};

const authReducer = (state = initialState, action) => {
  switch (action.type) {
    case types.AUTH_LOGIN:
      return {
        ...state,
        username: action.username,
        isLoggedIn: true
      };
    case types.AUTH_LOGOUT:
      return initialState;
    default:
      return state;
  }
};

Example component part

 render() {
    const { auth } = this.props;
    return (
        auth ? <div>Logged in</div> : <div>Not logged in</div>
    )
  }

You can connect this component to store or get this auth prop from a container. connect example:

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(mapStateToProps)(App);
like image 132
devserkan Avatar answered Oct 12 '22 11:10

devserkan


Well, you should create a reducer with some kind of initial state, probably something like

const initialLoginState = {
  userInformation: null,
};

export default function login(state = initialLoginState, action) {
  switch (action.type) {
    case 'SET_USER_INFORMATION':
      return { ...state, userInformation: action.userInfo };
  }

  return state;
}

with the corresponding action

export const setUserInformation = (userInfo) => ({
  userInfo,
  type: 'SET_USER_INFORMATION',
});

Then, when you receive user information from your backend upon successful login, you dispatch setUserInformation to store the data in Redux. Then you can access it from anywhere through Store.getState().login.userInformation (assuming you've added the login reducer to your store through combineReducers, etc.

Also, I would look into how to use the connect HOC in the component(s) that are interested in accessing the value.

like image 1
topic Avatar answered Oct 12 '22 11:10

topic