Elad Karni Elad Karni - 3 months ago 28
React JSX Question

How to have text dynamically change with React, but not call the change in Render?

I'm trying to build a very simple app with

React
that will tell you how many days have past since a given date. I am using
React
,
Moments
, and
ReactJS Datepicker
as the foundation of this app for quick implementation.

I'm getting an
error
when I attempt to pick a date saying

warning.js:44
Warning: setState(...): Cannot update during an existing state transition (such as within 'render' or another component's constructor)


I understand it means I can't have a function update a
state
I am currently displaying due to
render
issues, but am having a hard time figuring out how I can get such functionality without updating it in the
render
method.

This is the current app:



import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import './App.css';
import 'react-datepicker/dist/react-datepicker.css';

class App extends Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this)
this.state = {
startDate: moment(),
dateDiff: moment(),
dateCheck: false
};
}
handleChange(date) {
this.setState({
startDate: date,
dateCheck: true
});
}
showDiff(date, dateCheck) {
if (dateCheck) {
this.setState({
dateCheck: false,
dateDiff: moment().startOf(date).fromNow()
});
}
}
render() {
return (
<div className="App">
<div className="DatePicker">
<DatePicker
selected={this.state.startDate}
onChange={this.handleChange}
showYearDropdown
dateFormatCalendar="MMMM"
isClearable={true}
placeholderText='Enter A Date' />

</div>
<div>
{this.showDiff(this.state.startDate, this.state.dateCheck)}
</div>
</div>
);
}
}

export default App;





I'm trying to have it update the number of calculated days every time a new date is selected, and thought the
dateCheck
flag would help, but it didn't.

Thanks

Answer

React automatically re-renders parts of the DOM that need updating upon state change. The idea is to tell React what you want it to render, not how you want it to render.

So in your case, if you just want React to render the date difference from now, you need only change startDate when it updates. Here's some code to try to illustrate what I'm suggesting:

import React, { Component } from 'react';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import './App.css';
import 'react-datepicker/dist/react-datepicker.css';

class App extends Component {
  constructor() {
    super();
    this.handleChange = this.handleChange.bind(this)
    this.state = {
      startDate: moment()
    };
  }
  handleChange(date) {
    this.setState({
      startDate: date
    });
  }
  render() {
    return (
      <div className="App">
        <div className="DatePicker">
          <DatePicker
            selected={this.state.startDate}
            onChange={this.handleChange}
            showYearDropdown
            dateFormatCalendar="MMMM"
            isClearable={true}
            placeholderText='Enter A Date' />
        </div>
        <div>
          {this.state.startDate.fromNow()}
        </div>
      </div>
    );
  }
}

export default App;
Comments