1

How can I pass function with React Hooks? I've used useCallback, but it shows an error that it is not a function.

In class component I was doing it like this:

hidePopUp = (event) => {
    event.preventDefault();
    this.setState({
        popup: !this.state.popup
    })
}

Then I was passing function:

<Popup hidePopUp={this.hidePopUp}/>

That's my problem with Hooks:

const hidePopup = useCallback(
    (event) => {
        event.preventDefault();
        setPopup(!popup);
    }, []
);

<Popup hidePopup={() => hidePopup}/>

And this is my button in Popup component:

<button onClick={(event)=>this.props.hidePopUp(event)}></button>
Mateusz
  • 85
  • 1
  • 2
  • 6
  • In your first example, you're setting the `hidePopUp` prop to a function that takes a single argument. In your second example, you're setting the `hidePopUp` prop to a function *that takes no arguments, and returns a function*. Have you tried ``? – Joe Clay May 08 '19 at 14:20
  • You make a mistake in the name of the function. Prop name - `hidePopup`, function name - `hidePopUp`. 'Up' - from the upper case – Andrii Golubenko May 08 '19 at 14:21
  • 1
    2 silly mistakes, anyway thank you guys, it works. – Mateusz May 08 '19 at 14:29

2 Answers2

3

First of all spelling mistakes and some common mistakes in passing reference to same function. Otherwise it shouldn't be a problem at all passing the memoized version of this function at all.

Working demo here.

Second, there is no actual use of useCallback being seen here.

You should use a dependency to update your function to represent correct value of popup variable. Here's how:

const togglePopUp = useCallback(
    event => {
      event.preventDefault();
      setPopup(!popup);
    },
    [popup]
  );

Third, when you pass the function as prop, you can pass that directly the reference

<Popup hidePopup={togglePopUp}/>

Note - I've renamed your hidePopUp to togglePopUp

HalfWebDev
  • 7,022
  • 12
  • 65
  • 103
  • Would you be able to change the value of popup in the child component via the passed in function? ***in childComponent togglePopUp(true) – FernandoH-G Feb 12 '21 at 06:07
1

Actually, you can use pass the function without using useCallback(). I had the similar issue today. Then I realized that I need to add const before the variable which you declared to assign function. Simply, you should add const before hidePopUp() you created, because you are using arrow function there.

The updated version of your function should be:

const hidePopUp = (event) => {
    event.preventDefault();
    this.setState({
        popup: !this.state.popup
    })
}

Extra note: I am not saying using useCallback is false which other people advised. I want to emphasize that the problem you faced is not about callback.

Dharman
  • 30,962
  • 25
  • 85
  • 135