asynchronous - How to fire AJAX calls in response to the state changes with Redux? -


i'm converting existing state model redux , has been painless part. 1 point i'm having trouble converting "observed" state ajax requests. essentially, have ajax requests "linked" other pieces of state, no matter modifies them they'll issued correctly. can similar behavior subscribing redux store updates, firing actions in listener feels hack.

a possible solution move logic action creator via thunk pattern. problem i'd either have duplicate fetching logic across actions (since multiple actions modify "observed" state), or pull reducer logic action creator level. action creator shouldn't aware of how reducers respond issued actions.

i batch "sub-actions" need place appropriate fetching logic in each action "block", seems violate concept of actions producing valid state. i'd rather have liability @ action creator level.

are there accepted rules surrounding this? not simple application ad hoc ajax requests made components interacted with, data shared between multiple components , requests optimized , fetched in reaction state change.

tldr; want fire ajax requests in response changes in state, not when specific action happens. there better, "redux specific" way of organizing action/actioncreators mock behavior, other firing these actions in subscribe listener?

using store.subscribe()

the easiest way use store.subscribe() method:

let prevstate store.subscribe(() => {   let state = store.getstate()    if (state.something !== prevstate.something) {     store.dispatch(something())   }    prevstate = state }) 

you can write custom abstraction lets register conditions side effects expressed more declaratively.

using redux loop

you might want @ redux loop let describe effects (such ajax) calls together state updates in reducers.

this way can “return” effects in response actions return next state:

export default function reducer(state, action) {   switch (action.type) {     case 'loading_start':       return loop(         { ...state, loading: true },         effects.promise(fetchdetails, action.payload.id)       );      case 'loading_success':       return {         ...state,         loading: false,         details: action.payload       }; 

this approach inspired elm architecture.

using redux saga

you can use redux saga lets write long-running processes (“sagas”) can take actions, perform asynchronous work, , put result actions store. sagas watch specific actions rather state updates not asked for, figured i’d still mention them in case. work great complicated async control flow , concurrency.

function* fetchuser(action) {    try {       const user = yield call(api.fetchuser, action.payload.userid);       yield put({type: "user_fetch_succeeded", user: user});    } catch (e) {       yield put({type: "user_fetch_failed",message: e.message});    } }  function* mysaga() {   yield* takeevery("user_fetch_requested", fetchuser); } 

 no 1 true way

all these options have different tradeoffs. people use 1 or two, or 3 of them, depending on turns out convenient testing , describing necessary logic. encourage try 3 , pick works best use case.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -