-
-
Notifications
You must be signed in to change notification settings - Fork 98
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
Allow createReducer to be used without initial state #259
Comments
Hey @lnhrdt, thanks for sharing your feedback. Could you please provide the usage examples for your use case so I could fully understand what is the source of confusion. Thanks Also please understand this library wasn't designed to be used in such a way but let me see so I can explain what is the root issue here and perhaps work out a new developer friendly utility that would be designed for such usage. |
Hello @piotrwitek! Thanks for getting back to me and apologies for the delay. Here's an annotated example. import React, {Reducer, useReducer} from 'react'
import {ActionType, createAction, createReducer, getType} from 'typesafe-actions'
type State = {
height: number
}
const actions = {
addHeight: createAction('ADD_HEIGHT')<number>(),
doubleHeight: createAction('DOUBLE_HEIGHT')(),
}
type Action = ActionType<typeof actions>
/*
* We don't need to declare an initial state with this reducer.
* The useReducer hook requires it anyway down below, so this is good.
* */
const switchReducer: Reducer<State, Action> = (prevState, action) => {
switch (action.type) {
case getType(actions.addHeight): {
return {
height: prevState.height + action.payload
}
}
case getType(actions.doubleHeight): {
return {
height: prevState.height * 2
}
}
}
}
const AppWithSwitchReducer = () => {
/*
* Using React's useReducer here, we are required to provide the initial state.
* */
const [state, dispatch] = useReducer(switchReducer, {height: 0})
return (
<div>
<div>height: {state.height}</div>
<button onClick={() => dispatch(actions.addHeight(5))}>add 5</button>
<button onClick={() => dispatch(actions.doubleHeight())}>double</button>
</div>
)
}
/*
* This builder patter is super cool, compact, and readable!
* But there is no way to use it without providing an initial state.
* This is unfortunate because while in this example the state is simple,
* in realistic cases the state is very complex and having initial state in 2 places is confusing.
* I wish we could use the builder pattern without providing an initial state here.
* */
const builderReducer: Reducer<State, Action> = createReducer<State, Action>({height: 0})
.handleAction(actions.addHeight, (state, action) => ({height: state.height + action.payload}))
.handleAction(actions.doubleHeight, (state) => ({height: state.height * 2}))
const AppWithBuilderReducer = () => {
/*
* Again, React's useReducer requires us to provide the initial state.
* */
const [state, dispatch] = useReducer(builderReducer, {height: 0})
return (
<div>
<div>height: {state.height}</div>
<button onClick={() => dispatch(actions.addHeight(5))}>add 5</button>
<button onClick={() => dispatch(actions.doubleHeight())}>double</button>
</div>
)
} Does that help clarify the way I'm trying to use your library? |
Hello @piotrwitek were you able to read through my example or do you have any questions? |
Hey @lnhrdt thanks a lot for clarification, it's clear! I just missed your notification. I will have a look this week, but I agree with you that this is a generic pattern that could be a nice fit into the library. Let me check the details so I can prepare a proposal for such a feature. |
Believe it or not, we're still using the library and still wishing for this feature. Any chance of continued development in this project @piotrwitek, or have you moved on? |
Hey @piotrwitek! We ended up moving to a new solution in our application. I thought I'd mention it here in case you ever come back to this issue–we've already moved on and wouldn't benefit from the feature anymore. Thank you for this library, regardless. We used it happily for a long time. |
We are using createReducer throughout a React application. We always use these reducers with React's useReducer hook. In this scenario it is cumbersome to supply the initial state to both createReducer and to useReducer. It's especially cumbersome when the initial state is initialized by the runtime context – I can build the state at runtime and pass it to useReducer, but then the initial state passed to createReducer is not used. Understanding which initial states are real and which ones are just placeholders that will never be used has been a source of confusion for our team.
Ideally we could just rely on the type parameter passed to createReducer to build a reducer rather than also having to supply an initial state that may never be used.
The text was updated successfully, but these errors were encountered: