Welp
Welp

Reputation: 416

get returned state by ACTION CREATOR immediately

How do i get the value of the state right after the dispatch of an action? If state, it will be as simple as an arrow function in setState like:

this.setState({ test: true }, () => {
console.log("hey im loggin!!"
})

But what about if action creator is used: for example I have this in my connect function:

export default connect({mapStateToProps, { loginUser }})(Home);

how to do it like this?

this.props.loginUser(, () => {
console.log("of course this code does not work")
});

the .then() is not working..

currenty I am using a function and is injected immediately in the component which is i feel not the right thing to do... like this:

test() {
 this.props.loginUser(email, password);
 console.log(this.props.user) 
}

in my component

return (<div>{this.test()}</div>)

EDIT: MY ACTIONS AND REDUCERS btw

import axios from 'axios';
import { LOGIN, LOGIN_SUCCESS, LOGIN_ERROR } from './types';

const API_URL = 'http://localhost:8000/';

export const loginUser = (email, password) => {
    return (dispatch) => {
        dispatch({ type: LOGIN })

        axios.post(`${API_URL}v1/login`, { email, password })
            .then( user => {
                dispatch({
                 type: LOGIN_SUCCESS,
                 payload: user.data.user })
            })
            .catch( error => {
                dispatch({ type: LOGIN_ERROR, payload: error })
            })
    };
};

reduer:

import { LOGIN, LOGIN_SUCCESS, LOGIN_ERROR } from '../actions/types';

const INITIAL_STATE = {
    loading: false,
    user: [],
    message: '',
    error: false,
};

export default (state = INITIAL_STATE, action) => {
    switch(action.type) {
        case LOGIN:
            return { ...state, loading: true }
        case LOGIN_SUCCESS:
            return { ...state, loading: false, user: action.payload, error: false, message: '' }
        case LOGIN_ERROR:
            return { ...state, loading: false, error: true, message: action.payload }
        default:
            return state
    }
};

app js

<Provider store={createStore(store, {}, applyMiddleware(thunk))}>
        <Router>
          <div>
            <Route exact path="/" component={LoginForm} />
            <Route path="/home" component={Home} />
            <Route path="/profile" component={Profile} />
          </div>
        </Router>
      </Provider>

Upvotes: 2

Views: 467

Answers (2)

WitVault
WitVault

Reputation: 24140

Following steps may help you -

  1. Here you need to dispatch async-action from your action-creators
  2. Use"redux-thunk" or "redux-saga" for that
  3. You can access the state and create some async action

Using redux-thunk

import { Provider } from 'react-redux';
import { createStore,combineReducers, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import reducers from './reducers';

let reducer = combineReducers(reducers)
// applyMiddleware supercharges createStore with middleware:
const createStoreWithMiddleware = createStore(reducer, applyMiddleware(thunkMiddleware))
ReactDOM.render(
  <Provider store={createStoreWithMiddleware}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Just for an example -

export function fetchUser(userId) {
    return dispatch => {
        return Api.fetchUser(userId)
            .then( res => {
                dispatch(updateUserDetail(res));
            });
    };
}

Api.fetchUser is abstraction to your axios call to get user details.

export function updateUserDetail(userRes) {
    return {
        type : UPDATE_USER_DETAILS,
        userRes
    };
}

Upvotes: 1

egig
egig

Reputation: 4430

I believe the actions will return Promise, so you could do it like:

this.props.fetchUser().then(() => {
  console.log("do something")
});

NOTE that you need return the Promise/dispatch in your actions

return axios.post(`${API_URL}v1/login`, { email, password })
            .then( user => {
                return dispatch({
                 type: LOGIN_SUCCESS,
                 payload: user.data.user })
            })
            .catch( error => {
                return dispatch({ type: LOGIN_ERROR, payload: error })
            })

Upvotes: 3

Related Questions