André Vermeulen
André Vermeulen

Reputation: 1834

Using ReactRouter withRouter doesn't work with a React Hook

It seems that I can not use a React Hook useState inside of a Functional component that is wrapped in a withRouter function call for React Router.

I need the withRouter call to get URL parameters from the browser.

function TheComponent(props) {
    const { id } = props.match.params;
    // this is returning null for both done & setDone
    const {done, setDone} = useState(false);

    // some code that's using id

    return <div>
       // some tags here
    </div>
}

export default withRouter(function(props) {
     return <TheComponent {...props} {...this}  />
});

Adding the withRouter stops the Hook from working it seems.

How do I get around this?

I tried to add the Hook in the function call, but that didn't work:

export default withRouter(function(props) {
     const {done, setDone} = useState(false);
     return <TheComponent {...props} {...this} done={done} setDone={setDone}  />
});

The main thing I need to understand I suppose is what is the limitations of Hooks? It seems that they can't be declared inside the withRouter HOC function. Is that correct? And how can I get around this as I need to user the URL parameters for which I need the withRouter function.

Upvotes: 0

Views: 1608

Answers (3)

Vinicius Vieira
Vinicius Vieira

Reputation: 398

The main problem with your code is that your not getting the props in the constructor of TheComponent, but in case it breaks the rules of hooks, you can use this other aproach.

const TheComponent = (match) => {
        //you can destruct from props direct on parameters if you want
        const { id } = match.params;
        const [done, setDone] = useState(false);

        return <div>
           // some tags here
        </div>
    }

    export const WrapperComponent = withRouter((props) => {
      //you can destruct from props direct on parameters if you want
      const { match } = props;
      return <TheComponent match={match} />
    });

Upvotes: 0

jmclellan
jmclellan

Reputation: 550

You are using the wrong syntax for what the useState function returns. You should use square brackets instead of curly braces.

From the React docs for useState:

const [fruit, setFruit] = useState('banana');

When we declare a state variable with useState, it returns a pair — an array with two items. The first item is the current value, and the second is a function that lets us update it. Using [0] and 1 to access them is a bit confusing because they have a specific meaning. This is why we use array destructuring instead.

Edit: As others have said you should also be passing a props value as a parameter into your function.

Upvotes: 2

Ga&#235;l S
Ga&#235;l S

Reputation: 1599

You forgot to add arguments to your components:

function TheComponent(props) {
    const { id } = props.match.params;
    // this is returning null for both done & setDone
    const {done, setDone} = useState(false);

    // some code that's using id

    return <div>
       // some tags here
    </div>
}

Upvotes: 0

Related Questions