user3188348
user3188348

Reputation: 433

a React-Redux Action Update Multiple Reducers

How an Action update multiple different Reducers? How can i implement like this?

enter image description here

UPDATE:

this is my action in ./actions/sync.js. this action connected to an external API and call from Sync Component, periodically.

export function syncFetch(response) {
    return {
        type: 'SYNC_FETCH',
        response
    }
}

export function syncFetchData(url) {
    return (dispatch) => {
        fetch(url)
            .then((response) => {
                if (!response.ok) {
                    throw Error(response.statusText);
                }

                return response;
            })
            .then((response) => response.json())
            .then((sync) => updateAll(sync))
            .catch(() => console.log('error'));          
    };
}

const updateAll = (params) => {
    return dispatch => {
        dispatch({type: 'SYNC_FETCH', payload: params})
    }
}

and ./reducers/sync.js

const initialState = [];

export default (state = initialState, action) => {
    switch(action.type) {
        case 'SYNC_FETCH':
            return action.response;

        default:
            return state;
    }
}

i got not error, but data not update. what is problem in my code?

Upvotes: 11

Views: 6975

Answers (3)

Felix Too
Felix Too

Reputation: 11931

From react-redux 7.1, you can leverage the batch API to dispatch all the actions on a single re-render. From the docs you can do something like:

import { batch } from 'react-redux'

function myThunk() {
  return (dispatch, getState) => {
    // should only result in one combined re-render, not two
    batch(() => {
       dispatch(newsAction(newsParam))
       dispatch(userAction(newsParam))
       dispatch(notifyAction(newsParam))
    })
  }
}

Upvotes: 5

Shubham Khatri
Shubham Khatri

Reputation: 281774

each action is being dispatched to all the reducers, the reducers may decide whether they wish to use the action to update something or not

What you want is to

const updateAll = params => {
    return {type: 'UPDATE_PARAMS', payload: params}
}

and then use it in different reducers like

const newReducer = (state= initialState, action) => {
   switch(action.type) {
      case 'UPDATE_PARAMS': return {
         ...state,
         // do some things here
      }
      ...
      default: return state;
   }
}

const userReducer = (state= initialState, action) => {
   switch(action.type) {
      case 'UPDATE_PARAMS': return {
         ...state,
         // do some things here
      }
      ...
      default: return state
   }
}

Upvotes: 10

Ignacio
Ignacio

Reputation: 1056

One way of doing this could be to fire batched actions. So you can have three different actions, one per reducer, and have a main action that takes care of all these three subsequently (or just add two actions under the first one). This can be done by using thunks (thunk middleware). To do something like, assuming they're async:

const updateAllNewsStuff = newsParam => {
  return dispatch => {
    dispatch(newsAction(newsParam))
    dispatch(userAction(newsParam))
    dispatch(notifyAction(newsParam))
  }
}

You could probably also look at this plugin to fire batched actions: https://github.com/tshelburne/redux-batched-actions

Upvotes: 5

Related Questions