BigAB / use-epic

Use RxJS Epics as state management for your React Components
MIT License
46 stars 4 forks source link

Return methods (action creators) instead of `dispatch` #6

Open BigAB opened 5 years ago

BigAB commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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