React component only changes state on second onClick event

LanceLafontaine

I have these two simplified React components, where the Times component is a child of the Create component (see below for code samples). The expected behavior is that initially, the Times component is not shown, but when the user clicks on the link with onClick, the Times component appears.

The components work as expected for the most part, but strangely, after clicking on the onClick link for the first time, the Times component does not appear and the Create component does not change state at all as is shown in the console. However, when clicking on the link a second time, the Create component does change state and rerenders, and the Times component is seen.

Create.jsx

import React from 'react';
import Times from './Times.jsx';

export default React.createClass({

  getInitialState: function () {
    return {times: false};
  },

  _change: function () {
    this.replaceState({times: true});
    console.log(this.state.times);
  },

  render: function () {
    return (
      <div id="create">
        <div id="outerbox">
          <a onClick={this._change}>Times</a>
          <Times shouldShow={this.state.times}/>
        </div>
      </div>
    );
  }
});

Times.jsx

import React from 'react';

export default React.createClass({

  propTypes: {
    shouldShow: React.PropTypes.bool.isRequired
  },

  getDefaultProps: function () {
    return {shouldShow: false};
  },

  getInitialState: function () {
    return {el: 'times'};
  },

  componentDidMount: function() {
    if (this.props.shouldShow === false) {
      this.setState({display: 'none'});
    } else {
      this.setState({display: 'block'});
    }
  },

  componentWillReceiveProps: function() {
    if (this.props.shouldShow === false) {
      this.setState({display: 'none'});
    } else {
      this.setState({display: 'block'});
    }
  },

  render: function () {
    return (
      <div id={this.state.el} style={{"display": this.state.display}}>
        <h1>Times</h1>
      </div>
    );
  }
});

Output of console.log

false
true

Why is the state of the Create component not being registered on the first click?

Bhargav Ponnapalli

The problem is here.

 componentWillReceiveProps: function() {
    if (this.props.shouldShow === false) {
      this.setState({display: 'none'});
    } else {
      this.setState({display: 'block'});
    }
  }

Which should be,

 componentWillReceiveProps: function(newProps) {
    if (newProps.shouldShow === false) {
      this.setState({display: 'none'});
    } else {
      this.setState({display: 'block'});
    }
  }

ComponentWillRecieveProps is a member function of the component class that gets called just before props are "applied". Which means that this.props are old Props. You should use newProps which is served to the function as an argument.

http://codepen.io/bhargav175/pen/gaJmKz


Also, I get the feeling that you are using a little more state than you need. You dont need the display as a state variable at all. Times is an inner component, so it makes sense to use props as much as possible and make them stateless.

There is a common misconception around that "props change don't affect the render, so lets use state". Props change results in rerender too, so always use props unless there is a strong reason and you really need to make an inner component intelligent. Using props in inner components, makes them dumb and easier to use.

http://codepen.io/bhargav175/pen/WQBpzP

   var Times = React.createClass({

  propTypes: {
    shouldShow: React.PropTypes.bool.isRequired
  },

  getDefaultProps: function () {
    return {shouldShow: false};
  },

  getInitialState: function () {
    return {el: 'times'};
  },



  render: function () {
    let display = this.props.shouldShow ? "block" : "none";
    return (
      <div id={this.state.el} style={{"display": display}}>
        <h1>Times</h1>
      </div>
    );
  }
});

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

React onClick event on component

From Dev

React: component only rendering new values on second onClick of button

From Dev

React - return component onClick event

From Dev

Unwanted state changes in a class component with React

From Java

How to use onClick event on react Link component?

From Dev

Meteor React component onClick event not working in IE

From Dev

onClick event isn't firing on React Component

From Dev

Testing onClick event on react component using Jasmine

From Dev

onClick event isn't firing on React Component

From Dev

React--Button onclick event not working in Component

From Dev

Prevent render on the Second Component when state changes for the first

From Dev

Make an onclick event react different when click second time

From Dev

Update React component when state changes, using a reference to itself

From Dev

react component does not reload after ajax request changes state

From Dev

React event listeners based on changes in state made with Redux

From Dev

React: Calling two event handlers onClick and changing style of child component

From Dev

React, onClick only works after second click, Axios, Async/Await

From Dev

Access props and state of current component in React JS within an event handler

From Dev

Why Native DOM event always reset React Component state

From Dev

Why Native DOM event always reset React Component state

From Dev

Trigger event when the state of child of another component changed in react

From Dev

How to only trigger one onClick function when inside a component also with onClick event?

From Dev

React - how to capture only parent's onClick event and not children

From Dev

React Js component rendering only once after state change

From Dev

Component not updating when state changes

From Dev

React — onClick in component instance?

From Dev

Handling an onClick on a component in React

From Dev

change state of Component A from onClick of component B

From Dev

OnClick event in React

Related Related

  1. 1

    React onClick event on component

  2. 2

    React: component only rendering new values on second onClick of button

  3. 3

    React - return component onClick event

  4. 4

    Unwanted state changes in a class component with React

  5. 5

    How to use onClick event on react Link component?

  6. 6

    Meteor React component onClick event not working in IE

  7. 7

    onClick event isn't firing on React Component

  8. 8

    Testing onClick event on react component using Jasmine

  9. 9

    onClick event isn't firing on React Component

  10. 10

    React--Button onclick event not working in Component

  11. 11

    Prevent render on the Second Component when state changes for the first

  12. 12

    Make an onclick event react different when click second time

  13. 13

    Update React component when state changes, using a reference to itself

  14. 14

    react component does not reload after ajax request changes state

  15. 15

    React event listeners based on changes in state made with Redux

  16. 16

    React: Calling two event handlers onClick and changing style of child component

  17. 17

    React, onClick only works after second click, Axios, Async/Await

  18. 18

    Access props and state of current component in React JS within an event handler

  19. 19

    Why Native DOM event always reset React Component state

  20. 20

    Why Native DOM event always reset React Component state

  21. 21

    Trigger event when the state of child of another component changed in react

  22. 22

    How to only trigger one onClick function when inside a component also with onClick event?

  23. 23

    React - how to capture only parent's onClick event and not children

  24. 24

    React Js component rendering only once after state change

  25. 25

    Component not updating when state changes

  26. 26

    React — onClick in component instance?

  27. 27

    Handling an onClick on a component in React

  28. 28

    change state of Component A from onClick of component B

  29. 29

    OnClick event in React

HotTag

Archive