I have a Header component which renders some links, depending on whether a user is signed in or not.
This component loads fine, displays signin and signup links fine. Clicking on those links takes me to those components, which function as they should. Once I sign in, the header changes to display a signout link.
However, when I sign out, things go wrong. The signin and signup links display fine, but they are no longer functional. Clicking on the signup link gives the following error:
Uncaught Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of
Signin
.
Clicking on the link again produces this:
bundle.js:4297 Uncaught TypeError: Cannot read property 'getHostNode' of null
I've read similar questions on here, and typically they involved someone trying to render an object as opposed to one of its properties. However, this isn't the case here-or am I missing something?
My code:
Header:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router';
class Header extends Component{
renderLinks(){
if(this.props.authenticated){
return <li className="nav-item ">
<Link className="nav-link" to="/signout">Sign Out</Link>
</li>
}else{
return [<li className="nav-item page-scroll" key={1}>
<Link className="nav-link page-scroll" to="/signin">Sign In</Link>
</li>,
<li className="nav-item" key={2}>
<Link className="nav-link page-scroll" to="/signup">Sign Up</Link>
</li>
]
}
}
render() {
return (
<div className="container-fluid header">
<nav className="navbar navbar-toggleable-md navbar-inverse bg-inverse">
<div className="navbar-nav">
<Link to="/" className="navbar-brand">
<img alt="Trellis" src="../../images/trellis.png" />
</Link>
<ul className="nav navbar-nav">
{this.renderLinks()}
</ul>
</div>
</nav>
</div>
);
}
}
function 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 * as actions from '../../actions';
import { connect } from 'react-redux';
import { Link } from 'react-router';
class Signin extends Component {
handleFormSubmit({ email, password }) {
this.props.signInUser({email, password});
}
renderInput(field) {
if(!field.className) { field.className = "form-control" }
if(!field.type) { field.type = "text" }
return (
<div>
<Field name={field.name} id={field.name} type={field.type} className={field.className} component="input" />
</div>
)
}
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 className="sign-in" onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
<fieldset className="form-group">
<label>Email:</label>
{this.renderInput({ name: "email", type: "email" })}
</fieldset>
<fieldset className="form-group">
<label>Password:</label>
{this.renderInput({ name: "password", type: "password" })}
</fieldset>
<div className="password-forgot">
<Link to="/reset-password">I forgot my password</Link>
</div>
{this.renderAlert()}
<button action="submit" className="btn btn-primary">Sign in</button>
</form>
)
}
}
function mapStateToProps(state){
return{errorMessage: state.auth.error};
}
Signin = connect(mapStateToProps, actions)(Signin)
export default reduxForm({
form: 'signin'
})(Signin)
Signout component:
import React, {Component} from 'react';
import {connect} from 'react-redux';
import * as actions from '../../actions';
class Signout extends Component {
componentWillMount() {
this.props.signOutUser();
}
render() {
return <div>Sorry to see you go!</div>;
}
}
export default connect(null, actions)(Signout);
Signin action:
export function signInUser(props) {
const { email, password } = props;
return function(dispatch){
axios.post(`${ROOT_URL}/signin`, {email, password})
.then(response => {
localStorage.setItem('user', JSON.stringify(response.data));
dispatch({ type: AUTH_USER });
browserHistory.push('/dashboard');
})
.catch((err) => {
console.log(JSON.stringify('login error:', err));
dispatch(authError(SIGNIN_FAILURE, 'Bad login credentials'));
});
};
}
Signout action:
export function signOutUser() {
localStorage.clear();
return { type: UNAUTH_USER };
}
errorMessage
? Just a string? Can you add that - Jayce444