简体   繁体   中英

How can I avoid slow get state from the Redux store?

I have App contains Tabs that gets data from API bassed on token I passed to the header request,

So in the login screen, i dispatch an action to save token after user login and it's saved well

But the issue is after user login and go to home screen "save token Action dispatched" I got error 401 unauthorized, and when I log Token in getting data function I got empty in the debugger although save token dispatched".

But when I open the app again after killing App and Go to Home " because I'm login before and save token, And I use redux-persist to save it so it's saved before when logging first time" its work fine!

So I don't know whats the wrong When Login at first time!

here's Home Screen Code snippet

 constructor(props) {
    super(props);
    this.state = {
      token: this.props.token,
    }
   }


  // Get all playList user created
  getAllPlayLists = async () => {
    const {token} = this.state;
    console.log(token); // After first time I login I got here empty, But after i kill the app or re-open it i got the token well :)
    let AuthStr = `Bearer ${token}`;
    const headers = {
      'Content-Type': 'application/json',
      Authorization: AuthStr,
    };

    let response = await API.get('/my_play_list', {headers: headers});
    let {
      data: {
        data: {data},
      },
    } = response;
    this.setState({playlists: data});
  };
  componentDidMount() {
      this.getAllPlayLists();
  }



const mapStateToProps = state => {
  console.log('is??', state.token.token); here's i got the token :\\
  return {
    token: state.token.token,
  };
};

export default connect(mapStateToProps)(Home);

Redux stuff

reducers

import {SAVE_TOKEN} from '../actions/types';

let initial_state = {
  token: '',
};
const saveTokenReducer = (state = initial_state, action) => {
  const {payload, type} = action;
  switch (type) {
    case SAVE_TOKEN:
      state = {
        ...state,
        token: payload,
      };
      break;
  }
  return state;
};

export default saveTokenReducer;

--

import {IS_LOGIN} from '../actions/types';

let initialState = {
  isLogin: false,
};

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case IS_LOGIN:
      state = {
        ...state,
        isLogin: true,
      };
      break;
    default:
      return state;
  }
  return state;
};

export default userReducer;

actions

import {SAVE_TOKEN} from './types';

export const saveToken = token => {
  return {
    type: SAVE_TOKEN,
    payload: token,
  };
};

-

import {IS_LOGIN} from './types';

export const isLoginFunc = isLogin => {
  return {
    type: IS_LOGIN,
    payload: isLogin,
  };
};

store

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
};

const rootReducer = combineReducers({
  user: userReducer,
  count: countPlayReducer,
  favorite: isFavoriteReducer,
  token: saveTokenReducer,
});

const persistedReducer = persistReducer(persistConfig, rootReducer);

Edit

I figure out the problem, Now in the Login function after getting the response from the API I dispatch two actions Respectively

facebookAuth = async()=>{
....
 this.props.dispatch(isLoginFunc(true));  // first

 this.props.dispatch(saveToken(token)); // second
....
}

But when I dispatch saveToken(token) firstly I can see the token in the debugger without problems!

So how can i handle it and dispatch two actions at the same time?

When response token get then redirect to page. Maybe should add callback function for action. For example:

This following code is for add record

addVideoGetAction(values, this.props.data, this.callBackFunction)

This callBackFunction is close the modal

callBackFunction = (value: any) => {
    this.setCloseModal();
};

You will use callback function in login action. This function will redirect to the page

This function call in saga. this following code

function* setAddOrUpdate(params: any) {
        params.callback(redirectPageParams);
}

In redux we should NEVER alter the state object in reducer ... we return a brand new object

const saveTokenReducer = (state = initial_state, action) => {
  const {payload, type} = action;
  switch (type) {
    case SAVE_TOKEN:
      state = {
        ...state,
        token: payload,
      };
      break;
  }
  return state;
};

Instead

const saveTokenReducer = (state = initial_state, action) => {
  const { payload, type } = action;
  switch (type) {
    case SAVE_TOKEN:
      return { ...state, token: payload };
    default:
      return state;
  }
};

Regarding dispatching two actions at the same time

const userReducer = (state = initial_state, { action, type }) => {
  switch (type) {
    case UPDATE_LOGIN:
      return { ...state, token: payload, isLogin: !!payload };
    default:
      return state;
  }
};

-

facebookAuth = async () => {
  this.props.dispatch(updateLogin(token));
};

-

import { UPDATE_LOGIN } from './types';

export const updateLogin = token => {
  return {
    type: UPDATE_LOGIN,
    payload: token,
  };
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM