Skip to content

Allowing setting a default signature for actions created in a slice. #729

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

Open
lebobbi opened this issue Sep 15, 2020 · 2 comments
Open
Labels
enhancement New feature or request TypeScript

Comments

@lebobbi
Copy link

lebobbi commented Sep 15, 2020

The current implementation of the createSlice by default creates an actionCreator with the signature for a single parameter.
In our application we are using the meta pretty much on every single action and sometimes the error properties of the flux standard actions as well.
And while redux toolkit has been great to reduce boilerplate, having to override the action with prepare for every single case kind of fails this purpose.
Is there a way we could add an extra property to the slice configuration where we could define the default signature for that slice generated action creators?

I was thinking something like this:

// An ordered array with name of params.
const defaultActionCreator = ['payload', 'meta', 'error'];
// An ordered array of tuples with name and default value of param.
const defaultActionCreator = [['payload', {}], ['meta', {}], ['error', false]]

And in the implementation would be something like this:

const slice = function createSlice({
    name: "someSlice",
    initialState: {},
    reducers: {
      getAll(state, action){},
      ...
    },
    defaultActionCreator: ['payload', ['meta', {}]],
})

Then the signature of the 'getAll' actionCreator would end up like this.

// Generated action creator
getAll(payload, meta = {});
@phryneas
Copy link
Member

phryneas commented Sep 15, 2020

This would have pretty heavy consequences in our types, which are already too complicated and are just bound to get more complicated due to #637.

So for now, I'm not really seeing this make it into RTK, but with #637, you will be able to do things like

createSlice({
  name,
  initialState,
  reducers: create => ({ // callback form
    addTodo: create.preparedReducer(
      (text: string) => ({payload: {text, id: nanoid()}}),
      (state, action) => void state.push(action.payload);
    )
  })
})

so from that point on you could have a method like

function withPayloadAndMeta<P,M>(){
  return function prepare(payload: P, meta: M) { return {payload, meta}; }
}

and use it like

createSlice({
  name,
  initialState,
  reducers: create => ({
    addTodo: create.preparedReducer(
      withPayloadAndMeta<string, number>(),
      (state, action) => void state.push(action.payload);
    )
  })
})

@EskiMojo14
Copy link
Collaborator

this would be a good use case for custom reducer creators (#3837):

const enhancedReducerCreator = {
  type: enhancedReducerCreatorType,
  create(reducer) {
    return preparedReducerCreator.create(withPayloadAndMeta(), reducer)
  }
}

createSlice({
  name,
  initialState,
  creators: { enhancedReducer: enhancedReducerCreator },
  reducers: (create) => ({
    addTodo: create.enhancedReducer<string, number>(
      (state, action) => void state.push(action.payload)
    )
  }),
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants