Oliver Watkins
Oliver Watkins

Reputation: 13539

Dispatching an action from an asynch call in Redux

I am converting my project from flux to redux.

The root component is very straight forward redux :

import React from "react";
import ReactDOM from "react-dom";

import { Provider } from 'react-redux'
import AppReducer from './AppReducer'
import { createStore } from 'redux'

const store = createStore(AppReducer)

ReactDOM.render(
  <Provider store={store}>
    //rest of application goes here
  </Provider>,
app);

Using mapToProps, mapToDispatch I can deal with behaviour at the compoment level just fine.

Now I am coming to server responses, ie asynch calls.

In my flux implementation I have a file a call 'Server' I have my AJAX call and a promise is returned which then calls AppDispatcher.dispatch :

function handleResponse(endpoint) {
  return function (err, res) {
    if (res && res.ok) {
      receiveData(endpoint, res);
    }
  };
}

function receiveData(endpoint, responseData) {
  AppDispatcher.dispatch(
    {
      type: ActionTypes.SERVER_RESPONSE,
      endpoint: endpoint,
      state: "ReponseIsOK",
      payload: responseData.body
    }
  );
  dispatch(endpoint, "CommunicationState.RESPONSE_OK", responseData.body);
}

How should I convert this into redux?

I need to somehow get to the dispatcher, and I was hoping something like this would work :

function receiveData(endpoint, responseData) {

let store = Provider.getStore();
  store.dispatch(
    {
      type: ActionTypes.SERVER_RESPONSE,
      endpoint: endpoint,
      state: "ReponseIsOK",
      payload: responseData.body
    }
  );
}

I have tried provider.store, provider.context.store and they also seem to not work.

I really just need access to the store so that I can fire events, but not sure how to access it.

Upvotes: 0

Views: 53

Answers (2)

Theo.T
Theo.T

Reputation: 9267

You just need to save a reference to the store when you create it with configureStore. You could just set up a getter if you'd like to access this from outside.

Pseudo code:

var store = configureStore()

// ...    

export function getStore() {
    return store
}

// ...

<Provider store={ store } />

Upvotes: 1

melmquist
melmquist

Reputation: 470

I'm pretty sure this is a situation to use Redux-Thunk, which allows you to dispatch actions asynchronously.

Here is the explanation from the docs:

Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.

I think you would first need to modify your creation of the store and pass in redux-thunk as a middleware and then you can modify your receiveData function to be something like this:

function receiveData(endpoint, responseData) {
    return (dispatch, getState) => {
        // DISPATCH YOUR ACTION WITH RESPONSE DATA
        // AND ACCESS THE REDUX STORE        
    }
}

Upvotes: 2

Related Questions