daamian3
daamian3

Reputation: 55

How to wrap React Hooks dispatch into function outside component

I was wondering if i could wrap dispatch action into function (for example class method). I have this component:

function Product({id}) {
   const {state, dispatch} = React.useContext(CartContext);

   return (
      <button onClick={() => dispatch({type: "remove", payload: id})}>Remove</button>
   )
}

What i want to achieve is to replace ugly looking dispatch call into more clear function like this:

<button onClick={() => Cart.remove(id))}>Remove</button>

Is it possible? I've tried by this way but hooks can't be called outside React component.

export default Cart {
   static remove = id => React.useContext(CartContext).dispatch({type: "remove", payload: id});
}

Upvotes: 1

Views: 1814

Answers (2)

Vencovsky
Vencovsky

Reputation: 31625

What you need is to create a custom hook

const useRemoveCart = () => {
   const {state, dispatch} = React.useContext(CartContext);

   return id => dispatch({type: "remove", payload: id})
}

And now you can use this hook and call the return of it.

function Product({id}) {
   const remove = useRemoveCart()

   return (
      <button onClick={() => remove(id)}>Remove</button>
   )
}

But I don't feel like this is the way to go.

Probably the max thing you could do is create a useCart hook that will return state and dispatch. Creating a custom hook only for one function isn't good, because if you need another function, you will have to do a lot of refactor or create a new hook, and you will have one hook for each function, which will be very bad.

If I was you, I would do this

const useCart = () => React.useContext(CartContext)

Now you don't need to import useContext and CartContext, only import useCart

And probably create variables instead of passing the hole string "remove" which can cause some typos.

const REMOVE_CART = 'remove'

And use it like

dispatch({type: REMOVE_CART, payload: id})

Now you will never have a typo in the 'remove' string because if you do, it will give you an error.

Upvotes: 3

rhigdon
rhigdon

Reputation: 1521

You shouldn't pass dispatch to child components. Child components should typically pass the data back up to the parent, and the parent should solely be responsible for the state in the case. I'd suggest a Helper function in Product that does this.

Upvotes: 0

Related Questions