Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for accessing the raw action and raw action creator #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

qwerty0981
Copy link

Add API for accessing raw action and raw action creator

This PR adds support for accessing the generated action type and having a minimal API for accessing the internal raw action creator. Having access to these pieces of information would cover the only use-case that I have found where the pre-loaded action creators created by hooks-for-redux were not sufficient, using redux middleware like redux-saga or redux-rx.

Both of the middleware mentioned above need to have access to the raw action type to be used effectively and redux-rx specifically needs access to the basic action creator for use in bindActionCreators().

Example

// counter.js
import { createReduxModule } from 'hooks-for-redux';

// Create the module just like normal
export const [ useCounter, { increment, decrement, incrementBy }] = createReduxModule("counter", 0, {
    increment: (state) => state + 1,
    decrement: state => state - 1,
    incrementBy: (state, delta) => state + delta
})

// 'increment' and 'decrement' can now be used the same as before
increment() // state: 0 -> 1
increment() // state: 1 -> 2
decrement() // state: 2 -> 1

// Now the action creator's internal type can be accessed
console.log(increment.type)  // "counter-increment"
console.log(decrement.type)  // "counter-decrement"

// And you can get access to the raw action creator for integration in other libraries
console.log(increment.toAction())    // { type: "counter-increment" }
console.log(decrement.toAction())    // { type: "counter-decrement" }
console.log(incrementBy.toAction(2)) // { type: "counter-incrementBy", payload: 2 }

Example usage in redux-saga (this integration was impossible before)

// sagaCounter.js
// Import action from the example above
import { incrementBy } from './counter'
import { call, put, takeLatest } from 'redux-saga/effects'

// import fake API
import * as API from './api'

// Saga action creator
const counterActionType = "REMOTE_COUNTER_ACTION"
export const callRemoteCounter = amountToChange => { return { type: counterActionType, payload: amountToChange }}

// Saga definition
function* counterSaga(action) {
    try {
        const canIncreaseCounter = yield call(API.callRemoteCounterMethod, action.payload);
       
        if (canIncreaseCounter) {
            yield put(incrementBy.toAction(action.payload));
        } else {
            // do nothing (there would be some failure logic like setting a not authorized error
        }
    } catch (e) {
       // do nothing (there would be some failure logic like setting a remote call failed error
   }
}

// Create Saga to be included in store creation
function* counterSagas() {
  yield takeLatest(counterActionType, counterSaga);
}

@shanebdavis
Copy link
Member

Thanks for this submission!

I wish Github notified me of it ;). I'm just noticing it now. I'll dive in deeper in a bit and see if it fits.

@shanebdavis
Copy link
Member

Quick glance at the changes... looks pretty good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants