Skip to content

Instantly share code, notes, and snippets.

@safx
Last active May 4, 2023 09:37
Show Gist options
  • Save safx/da7c0d1d23b582013f082a6d1b947117 to your computer and use it in GitHub Desktop.
Save safx/da7c0d1d23b582013f082a6d1b947117 to your computer and use it in GitHub Desktop.
React Router Redirects (Auth) Example with React Context and TypeScript
import * as React from 'react';
import { BrowserRouter as Router, Link, Redirect, Route, RouteComponentProps, withRouter } from 'react-router-dom';
const UserAuthContext = React.createContext({
authenticated: false,
setAuthenticated: (_:boolean) => {}
});
const AuthExample = () => (
<Router>
<div>
<AuthButton />
<ul>
<li>
<Link to="/public">Public Page</Link>
</li>
<li>
<Link to="/protected">Protected Page</Link>
</li>
</ul>
<Route path="/public" component={Public} />
<Route path="/login" component={Login} />
<PrivateRoute />
</div>
</Router>
);
const AuthButton = withRouter(
({history}) =>
<UserAuthContext.Consumer>
{({authenticated, setAuthenticated}) => (
authenticated ? (
<p>
Welcome!{" "}
<button
onClick={() => {
setAuthenticated(false);
history.push("/");
}}
>
Sign out
</button>
</p>
) : (
<p>You are not logged in.</p>
)
)}
</UserAuthContext.Consumer>
);
const PrivateRoute: React.SFC<{}> = props => {
return (
<UserAuthContext.Consumer>
{({authenticated}) => (
<Route path="/protected" render={props =>
authenticated ? (
<Protected />
) : (
<Redirect to={{ pathname: "/login", state: { from: props.location } }} />
)
} />
)}
</UserAuthContext.Consumer>
);
};
const Public = () => <h3>Public</h3>;
const Protected = () => <h3>Protected</h3>;
class Login extends React.Component<RouteComponentProps<{}>> {
state = {
redirectToReferrer: false
};
render() {
const { from } = this.props.location.state || { from: { pathname: "/" } };
const { redirectToReferrer } = this.state;
if (redirectToReferrer) {
return <Redirect to={from} />;
}
return (
<UserAuthContext.Consumer>
{({authenticated, setAuthenticated}) => (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={() => {
setAuthenticated(true);
this.setState({ redirectToReferrer: true });
}}>Log in</button>
</div>
)}
</UserAuthContext.Consumer>
);
}
}
class App extends React.Component {
setAuthenticated = (authed: boolean) => {
this.setState(state => ({
authenticated: authed
}));
};
state = {
authenticated: false,
setAuthenticated: this.setAuthenticated
}
public render() {
return (
<UserAuthContext.Provider value={this.state}>
<AuthExample />
</UserAuthContext.Provider>
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment