use-epic icon indicating copy to clipboard operation
use-epic copied to clipboard

Return methods (action creators) instead of `dispatch`

Open BigAB opened this issue 6 years ago • 2 comments

Is your feature request related to a problem? Please describe.

Having to define a lot of callbacks from the dispatch method can be tedious:

const [
  { restaurant },
  dispatch,
] = useEpic(restaurantFilterEpic);

const handleRegionChange = useCallback(e => dispatch(['SELECT_REGION', e.target.value])), dispatch);
const handleCityChange =  useCallback(e => dispatch(['SELECT_CITY', e.target.value]));
const handleRestaurantChange =  useCallback(e => dispatch(['SELECT_RESTAURANT', target.value]));

return <RestaurantSelector
  restaurant={restaurant}
  onRegionChange={handleRegionChange}
  onCityChange={handleCityChange}
  onRestaurantChange={handleRestaurantChange}
/>

Describe the solution you'd like I'd like an option, to receive action creator style methods instead of the dispatch, perhaps something like:

const [
  { restaurant },
  { handleRegionChange, handleCityChange, handleRestaurantChange },
] = useEpic(restaurantFilterEpic, {
    actions: {
      handleRegionChange: ['SELECT_REGION', e => e.target.value],
      handleCityChange: ['SELECT_CITY', e => e.target.value],
      handleRestaurantChange: ['SELECT_RESTAURANT', e => e.target.value],
    }
  });

return <RestaurantSelector
  restaurant={restaurant}
  onRegionChange={handleRegionChange}
  onCityChange={handleCityChange}
  onRestaurantChange={handleRestaurantChange}
/>

The actions option should memoize the callbacks, but in a more efficient way than useCallback

Describe alternatives you've considered

After writing the examples I have to question: Is it worth it, the amount of code written is pretty close, maybe this isn't the best idea?

BigAB avatar Oct 24 '19 15:10 BigAB

Maybe a better approach would be to allow the Epic function define the action creators?

const restaurantFilterEpic(actions$, state$) {/*...*/}
restaurantFilterEpic.actions = {
      handleRegionChange: ['SELECT_REGION', (e) => e.target.value],
      handleCityChange: ['SELECT_CITY', (e) => e.target.value],
      handleRestaurantChange: ['SELECT_REGION', ([e) => e.target.value],
}

BigAB avatar Oct 24 '19 16:10 BigAB

In retrospect, in my last comment, the e => e.target.value does not belong there

BigAB avatar Oct 24 '19 16:10 BigAB