Gagan Sharma
Gagan Sharma

Reputation: 262

console.log is printing data two times [reactjs]

console.log is printing the value two times once it is printing the empty array and in the other value it is printing the value obtained from the ajax call.

With the value given below it printing like '[]' and ["answered"]

I don't know where it is getting initialised where i am putting a debugger on it it is stopping only once over there just for printing the ajax data value

{ "status": 1, "value": 4, "data": { "answer_text": "answered" } }

class Discuss extends React.Component {
  constructor() {
    super();
    this.state = {
      discussions: []
    };
  }
  componentWillMount() {
    this._getData();
  }
  _getAnswerText() {
    return this.state.discussions.map(discussion => discussion.answer_text);
  };

  render() {
    const comments = this._getComments();
    return ( <div> {comments} <ActionBar answer_text={this._getAnswerText()}/></div > );
  });
}

_getData() {
  $.ajax({
    method: 'GET',
    url: '/someurl'
    success: (discussions) => {
      var array = [];
      array.push(discussions);
      var dis = []
      dis.push(array[0].data)
      this.setState({
        discussions: dis
      });
    }
  });
}
}

class ActionBar extends React.Component {
    constructor(props) {
      super(props);
    };
    render() {
        console.log(this.props.answer_text)
        return ( <div> {this.props.answer_text} </div>)
	};

}

ReactDOM.render(<Discuss/>,document.getElementById('content'));

Upvotes: 5

Views: 14209

Answers (4)

Unais Kalathingal
Unais Kalathingal

Reputation: 1

remove the StrictMode from index.js

<React.StrictMode>

<App />

</React.StrictMode>

Upvotes: 0

Aamir Usmani
Aamir Usmani

Reputation: 49

React.StrictMode is a wrapper introduced in version 16.3.0 back in 2018. At first, it was applied only for class components and after 16.8.0 it is applied also for hooks.

As mentioned in the release notes: React.StrictMode is a wrapper to help prepare apps for async rendering

Why the double rendering then? One of the benefits that we get from React.StrictMode usage, is that it helps us to detect unexpected side effects in the render-phase lifecycles.

You can read more about it on this link:

https://mariosfakiolas.com/blog/my-react-components-render-twice-and-drive-me-crazy/

Upvotes: 4

Jyothi Babu Araja
Jyothi Babu Araja

Reputation: 10292

If you really want to log the data from props, keep that log in componentWillReceiveProps(). Since it's fired for every new props from parent Component

componentWillRecieveProps(nextProps){
    console.log(nextProps.answer_text); //you can log data from props here to check
}

And your render() method will be called whenever there is change in props and state. i.e Whenever your shouldComponentUpdate() of React.Component returns true.

So it's obvious that you will see execution your render() method more than once if there is change in your data(props or state).

Read more from here about React Component and it's life cycle.

Updated: If you have empty data just return null in render()

class Discuss extends React.Component {
  constructor() {
    super();
    this.state = {
      discussions: []
    };
  }
  componentWillRecieveProps(nextProps){
    console.log(nextProps.answer_text); //you can log data from props here to check
  }
  componentWillMount() {
    this._getData();
  }
  _getAnswerText() {
    return this.state.discussions.map(discussion => discussion.answer_text);
  };

  render() {
    const comments = this._getComments();
    return ( <div> {comments} <ActionBar answer_text={this._getAnswerText()}/></div > );
  });
}

_getData() {
  $.ajax({
    method: 'GET',
    url: '/someurl'
    success: (discussions) => {
      var array = [];
      array.push(discussions);
      var dis = []
      dis.push(array[0].data)
      this.setState({
        discussions: dis
      });
    }
  });
}
}

class ActionBar extends React.Component {
    constructor(props) {
      super(props);
    };
    render() {
      const {answer_text} = this.props;
        return ( 
          <div>
                { answer_text && answer_text.length > 0 || null} 
          </div>
        )
	};

}
                

ReactDOM.render(<Discuss/>,document.getElementById('content'))

Upvotes: 2

Jeff McCloud
Jeff McCloud

Reputation: 5927

This is normal. The AJAX call is asynchronous, so your component continues to render immediately, the first time with empty array in its state which is passed on as a prop to ActionBar. When the AJAX call returns, it populates the array and updates state, which causes render() to be called again, which re-renders ActionBar along with the updated prop.

Upvotes: 3

Related Questions