Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrap a React route render function in a HOC

I am using React-Router 4 to create some routes. (It uses the PrivateRoute component from the official docs but that's not relevant to this question.)

<HashRouter>    
    <Switch>
        <PrivateRoute exact path='/' component={Wrapper(Home)} />
        <Route exact path='/login' render={(props) => <Login authenticate={this.authenticate} {...props} />} />
        <PrivateRoute exact path='/clients' component={Wrapper(Clients)} />
    </Switch>
</HashRouter>

As you can see the Home and Clients components are wrapped in an HOC. For the moment this does nothing:

const Wrapper = (Page) => {
    return (props) => (
        <div className="page">
            <p>This should be on every page</p>
            <Page {...props} />
        </div>
    );
}

This works fine. What I can't figure out is how to wrap the Login route in the same HOC. I've tried

<Route exact path='/login' render={(props) => Wrapper(<Login authenticate={this.authenticate} {...props} />)} />

But this returns the error:

Route.render(): A valid React element (or null) must be returned.

like image 271
GluePear Avatar asked Oct 29 '22 03:10

GluePear


1 Answers

Can you try doing it like that:

<Route exact path='/login' render={(props) => Wrapper(Login)({...props, authenticate: this.authenticate})} />

Because now Wrapper HOC is returning a function, but the react element is expected. To get the react element we'll need to call this function with the needed props and that seems like a good place to add that extra prop this.authenticate.

Here's a quick snippet I made: https://stackblitz.com/edit/react-zestnq

like image 81
Gleb Kostyunin Avatar answered Nov 10 '22 19:11

Gleb Kostyunin