Redux - Saga, put parent function

Viewed 307

There is a way to call a props function (which is passed by the parent component, not in the current component), in saga container after a specific request?

This is my example

saga.js

export function* getItem(options) {
    try {
        const url = `....`;
        const response = yield call(request, url);
        // here setResponse is an action that modify reducer and it's fine
        yield put(setResponse(response));
        // here I want to put a props parents function(something like this), but in sagas I dont't have access to props
        yield put(this.props.parentFunction)
    } catch (e) {
        .....
    }
}

The only way I found is to use a callback(so I call the props to function in index.js and exist) or pass directly the function as getItems options.

There is a cleaner way?

2 Answers

I'm not sure I fully understand your goal, but I've faced a similar challenge -

I need to run this function after my saga completes.

Usually it's presentation or component-related (e.g. hide a spinner). Redux-Form, for example, takes a Promise-creating submit handler. How do we transform a saga call into a promise?

So like you've suggested, we could pass the function around. OR, we could go the other direction -- "how can my component subscribe to redux events?"

You can definitely hack something together that works for your use-case, but I use redux-saga-thunk for this. It allows saga-running action dispatch calls to return a promise: this.props.runSaga().then(...

As a bonus, you also get "derived state" selectors like pending(ACTION_NAME), which is very handy for showing loading UI without manually managing boolean flags.

Assuming parentFunction is pure. You can achieve that by passing parentProps as an argument in addition to options to your action. Here is the pattern:

Here, getItemsAction gets 2 arguments:

  • options: some data
  • parentProps: props from parent component
export const function getItemsAction(options, parentProps){
    return ({ type: GET_ITEMS_REQUEST, payload: {options , parentProps} });
}

By providing these parameters to the action, these will be available to you inside the saga (i.e options & parentProps):

export function* getItemsSaga({ ...payload }) {
    try {
        const url = `....`;
        const response = yield call(request, url);
        // here setResponse is an action that modify reducer and it's fine
        yield put(setResponse(response));
        // here I want to put a props parents function(something like this), but in sagas I dont't have access to props
        yield put(parentProps)
    } catch (e) {
        .....
    }
}

This way parentFunction can be stored in parentProps, and accessed within the saga.

Related