animaonline
animaonline

Reputation: 3804

Subscribing to a redux action in a react component

I have an async thunk that fetches some information from a web service, it can dispatch three types of actions

FETCH_REQUESTED
FETCH_SUCCEEDED
FETCH_FAILED

Finally, if it's succeeded; it returns the actual response, or an error object.

I have a component that should detect whether the operation has failed or not, preferably by subscribing to the FETCH_FAILED action and displaying an error message based on the type of the error (404/401 and other status codes)

export const fetchData = () => {
    return async (dispatch, getState) => {
        const appState = getState();

        const { uid } = appState.appReducer;

        await dispatch(fetchRequested());

        try {
            const response = await LookupApiFactory().fetch({ uid });

            dispatch(fetchSucceeded(response));

            return response;
        } catch (error) {
            dispatch(fetchFailed());

            return error;
        }
    }
}

I'm quite new to redux and react, so I'm a bit unsure if I'm heading in the right direction, any help would be appreciated.

Upvotes: 7

Views: 15869

Answers (3)

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

Assuming reducers,

for FETCH_FAILED action,you can put some meaningful flag indicating there are some failure.Based on that flag you can show error messages or do other action.

const testReducers =(state,actione)=>{

    case 'FETCH_FAILED' : {

        return {
            ...state,{ error_in_response : true }
        }
    };

    default : return state;
}

In your container,you can get that flag and passed it to your component.

Assuming combineReducers used to combine reducers;

const mapStateToProps=(state)=>{

    return {
        error_in_response : state.testReducers.error_in_response
    }
}
connect(mapStateToProps)(yourComponent)

In your component, this can be accessed using this.props.error_in_response

Upvotes: 0

Yuriy Yakym
Yuriy Yakym

Reputation: 3911

The most common approach is to use connect function from react-redux library. This is a HoC which subscribes to state changes. Take a look at this library, additionally it allows you to bind your action creators to dispatch, what gives you an ability to dispatch your actions from component.

You can use it like this:

import React from 'react';
import { connect } from 'react-redux';

const MyComponent = ({ data, error }) => (
  <div>
    {error && (
      <span>Error occured: {error}</span>
    )}

    {!error && (
      <pre>{JSON.stringify(data, null, 2)}</pre>
    )}
  </div>
);

const mapStateToProps = (state) => ({
  data: state.appReducer.data,
  error: state.appReducer.error
});

export default connect(mapStateToProps)(MyComponent);

You can use conditional rendering inside your jsx as I've shown above, or use guard clause, like this:

const MyComponent = ({ data, error }) => {
  if (error) {
    return (
      <span>Error occured: {error}</span>
    );
  }

  return (
    <pre>
      {JSON.stringify(data, null, 2)}
    </pre>
  );
}

Upvotes: 0

Rohith Murali
Rohith Murali

Reputation: 5669

To implement a proper redux call back and storage mechanism you should have a store to keep all your data,

const store = createStore(todos, ['Use Redux'])

then, you dispatch data to store,

store.dispatch({
  type: 'FETCH_FAILED',
  text: reposnse.status //Here you should give the failed response from api
});

Then you can get the value from the store in any of your components using a subscribe function. It will be called any time an action is dispatched, and some part of the state tree may potentially have changed.

store.subscribe(()=>{
  store.getState().some.deep.property
})

This is a simple implementation of Redux. As your app grows more complex, you'll want to split your reducing function into separate functions, each managing independent parts of the state using combineReducers. You can get more information from redux.js site

Upvotes: 5

Related Questions