Reputation: 262
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
Reputation: 1
remove the StrictMode from index.js
<React.StrictMode>
<App />
</React.StrictMode>
Upvotes: 0
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
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
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