I am creating signin/signout pages in react The header contains signin, signup or sign out links depending on whether the user is signed in or not. After Signing in, if the user clicks on sign out link he should be redirected to signout route. The url is changing to sign out route but the signout component is not being rendered. I can still see the signin component itself.
EDIT
The sign out component renders fine when I directly enter the url in the browser. It is not rendering only when the link (Link component in react-router-dom ) to signout route is clicked
Header component:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
class Header extends Component {
renderLinks() {
if(this.props.authenticated) {
return (
<li className="nav-item">
<Link to="/signout" className="nav-link">Sign Out</Link>
</li>
);
}
else {
return (
[
<li className="nav-item" key={1}>
<Link to="/signin" className="nav-link">Sign In</Link>
</li>,
<li className="nav-item" key={2}>
<Link to="/signup" className="nav-link">Sign Up</Link>
</li>
]
);
}
}
render () {
return (
<nav className="navbar navbar-light">
<Link to="/" className="navbar-brand">Redux Auth</Link>
<ul className="nav navbar-nav">
{this.renderLinks()}
</ul>
</nav>
);
}
}
const mapStateToProps = (state) => {
return { authenticated: state.auth.authenticated };
}
export default connect(mapStateToProps)(Header);
SignIn component:
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import * as actions from '../../actions';
class Signin extends Component {
handleFormSubmit({ email, password }) {
console.log(email, password);
this.props.signinUser({ email, password });
}
renderAlert() {
if(this.props.errorMessage) {
return (
<div className="alert alert-danger">
<strong>Oops!</strong> { this.props.errorMessage }
</div>
);
}
}
render() {
const { handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<div className="form-group">
<label>Email:</label>
<div>
<Field
className="form-control"
name="email"
component="input"
type="text"
/>
</div>
</div>
<div className="form-group">
<label>Password:</label>
<div>
<Field
className="form-control"
name="password"
component="input"
type="password"
/>
</div>
</div>
{this.renderAlert()}
<div>
<button action="submit" className="btn btn-primary">Sign In</button>
</div>
</form>
);
}
}
const mapStateToProps = (state) => {
return { errorMessage: state.auth.error };
}
Signin = reduxForm({
form: 'signin',
})(Signin);
export default Signin = connect(mapStateToProps, actions)(Signin);
Signout component:
import React, { Component } from 'react';
import Header from './header';
export default class Signout extends Component {
render() {
return <div>Sorry to see you go...</div>;
}
}
Main index file:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import reduxThunk from 'redux-thunk';
import App from './components/app';
import Signin from './components/auth/signin';
import Signout from './components/auth/signout';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router>
<div>
<Route path="/" component={App} />
<Route path="/signin" component={Signin} />
<Route path="/signout" component={Signout}/>
</div>
</Router>
</Provider>
, document.querySelector('.container'));
If you want to check out the entire code. It is present at this git repository
https://github.com/sruthisripathi/react-auth
EDIT
I tried using withRouter inside Header component as below
export default withRouter(connect(mapStateToProps)(Header));
I tried passing props to Header inside App component
<Header {...this.props} />
But none of this worked.
EDIT
Changing the signin and signout routes to App component instead of index file solved the issue.
App component:
import React, { Component } from "react";
import { Route } from "react-router-dom";
import Signin from "../components/auth/signin";
import Signout from "../components/auth/signout";
import Header from "./header";
export default class App extends Component {
render() {
return (
<div>
<Header />
<Route path="/signin" component={Signin} />
<Route path="/signout" component={Signout} />
<Route path="/signup" component={Signout} />
</div>
);
}
}
index.js file:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import reduxThunk from 'redux-thunk';
import App from './components/app';
import Signin from './components/auth/signin';
import Signout from './components/auth/signout';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router>
<div>
<Route path="/" component={App} />
</div>
</Router>
</Provider>
, document.querySelector('.container'));