MonkeyBonkey MonkeyBonkey - 9 days ago 6
React JSX Question

Why does adding an onClick method cause an infinite loop in my react render method

I have one line that seems to be causing an infinite loop. The issue occurs if I assign an onClick handler to my element.

So, in a render function, the following causes an infinite loop

button = <button onClick={ props.onLogin() }>Login</button>;


In contrast, the following does not cause a loop

button = <button>Login</button>;


Full code

import React, { Component, PropTypes } from 'react';
import { login, logout } from '../actions/user';
import { connect } from 'react-redux';

class Navbar extends Component {

render() {
const props = this.props;
const { user } = props;
const { isAuthenticated, errorMessage } = user;

let button;

// the onClick assignment below causes the infinite loop
if (isAuthenticated) {
button = <button onClick={ props.onLogout() }>Logout</button>;
} else {
button = <button onClick={ props.onLogin() }>Login</button>;
}

return (
<div>
<a href="/">Hello</a>
<div>
<div>{errorMessage}</div>
{ button }
</div>
</div>
);
}

}

Navbar.propTypes = {
user: PropTypes.object,
errorMessage: PropTypes.string,
};

const mapStateToProps = (state) => {
return {
user: state.user,
};
};

const mapDispatchToProps = (dispatch) => {
return {
onLogin: () => {
dispatch(login());
},
onLogout: () => {
dispatch(logout());
},
};
};

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

Answer

You don't need to invoke the function inside the onClick attribute, just pass the function, so it has to be:

  // the onClick assignment below causes the infinite loop
  if (isAuthenticated) {
    button = <button onClick={ props.onLogout }>Logout</button>;
  } else
    button = <button onClick={ props.onLogin }>Login</button>;
  }