lost9123193
lost9123193

Reputation: 11030

Proper way to Call Props in React

I have the following code:

function PrivateRoute({ component: Component, auth, ...rest }) {
    return (
        <Route
            {...rest}
            render={props =>
                auth === true ? (
                    <Component {...props} />
                ) : (
                    <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
                )
            }
        />
    );
}

function PublicRoute({ component: Component, auth, ...rest }) {
    return <Route {...rest} render={props => (auth === false ? <Component {...props} /> : <Redirect to="/dashboard" />)} />;
}

export default () => (
    <BrowserRouter>
        <Switch>
            <PublicRoute auth={true} path="/login" exact component={Login} />
            <PrivateRoute auth={true} path="/news" exact component={News} />
            <PrivateRoute auth={false} path="/blogs" exact component={Blog} />
            <Route render={() => <h3>No Match</h3>} />
        </Switch>
    </BrowserRouter>
);

I want to add this below to keep track of the authenticated prop:

function mapStateToProps(state) {
  return {
    auth: state.authenticated
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(?);

However, I'm not sure how to add it to the functional code. Would I need to convert the export default section to a class?

Upvotes: 0

Views: 86

Answers (2)

flppv
flppv

Reputation: 4289

First of all, please don't do unnamed default exports, you can rewrite it into this:

const MyRouter = (props) => (
    <BrowserRouter>
        <Switch>
            <PublicRoute auth={true} path="/login" exact component={Login} />
            <PrivateRoute auth={true} path="/news" exact component={News} />
            <PrivateRoute auth={false} path="/blogs" exact component={Blog} />
            <Route render={() => <h3>No Match</h3>} />
        </Switch>
    </BrowserRouter>
);

and then you can easily(Also note, that you can have only one default export from file).

export default connect(mapStateToProps, mapDispatchToProps)(MyRouter);

Note, that I added props as an argument to MyRouter component. Now you can use props inside of it and pass auth={props.auth} to your PrivateRoute components.

Upvotes: 1

DoHn
DoHn

Reputation: 673

However, I'm not sure how to add it to the functional code. Would I need to convert the export default section to a class?

No, you don't. You only need to convert a functional component to a class based component if you want to use state, lifecycle methods or refs (and arguably not even in these cases since the arrival of Hooks).

Simply put your exported component in a variable instead of exporting it, and use that variable with connect:

const RouterComponent = ({ auth }) => (
    <BrowserRouter>
        <Switch>
            <PublicRoute auth={auth} path="/login" exact component={Login} />
            <PrivateRoute auth={auth} path="/news" exact component={News} />
            <PrivateRoute auth={auth} path="/blogs" exact component={Blog} />
            <Route render={() => <h3>No Match</h3>} />
        </Switch>
    </BrowserRouter>
);

function mapStateToProps(state) {
  return {
    auth: state.authenticated
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({}, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(RouterComponent);

Upvotes: 1

Related Questions