I have a component that looks like:
class Table extends Component {
constructor(props) {
super(props);
this.columnDefs = columnDefs;
this.state = {
isLoading: true,
showTimeoutModal: false,
tableData: [],
currentDate: null
};
}
componentDidMount() {
this.fetchData();
}
fetchData() {
this.setState({
isLoading: true,
currentDate: this.props.currentDate
});
someApi.getData(this.props.currentDate).then(tableData => this.setState({
tableData: tableData,
isLoading: false
}))
.catch(error => {
if (error.message === 'timeout') {
this.setState({
showTimeoutModal: true
});
} else {
throw new Error(error.message);
}
});
}
onGridReady(params) {
this.gridApi = params.api;
this.gridApi.sizeColumnsToFit();
}
renderGrid() {
const { tableData, isLoading, showTimeoutModal } = this.state;
let currentView = null;
console.log(this.props.currentDate);
console.log(this.state.currentDate);
if (!isLoading) {
if (tableData) {
currentView =
<div>
<AgGridReact
columnDefs={this.columnDefs}
rowData={tableData}
pagination
paginationPageSize={25}
headerHeight="43"
onGridReady={params => this.onGridReady(params)}
rowSelection="single"
animateRows="true" />
</div>;
} else {
currentView = <h6>There is no job data to display!</h6>;
}
} else if (showTimeoutModal) {
currentView = <div>
<TimeoutModalComponent />
<h6>Timed out</h6>
</div>;
} else {
currentView = <LoadingComponent />;
}
return (
<div>
{currentView}
</div>
);
}
render() {
return (
<div>
{this.renderGrid()}
</div>
);
}
}
export default Table;
It gets the currentDate property from a datepicker component that looks like this:
class DatePicker extends Component {
constructor(props) {
super(props);
this.onDateChange = this.onDateChange.bind(this);
this.state = {
currentDate: moment(),
focused: false
};
}
onDateChange() {
this.setState({
currentDate: this.props.currentDate
});
}
render() {
return (
<div className="form-group">
<SingleDatePicker
date={this.state.currentDate}
onDateChange={this.onDateChange}
focused={this.state.focused}
onFocusChange={({ focused }) => this.setState({ focused: focused })}
/>
<TableComponent currentDate={`${this.state.currentDate}`} onDateChange={this.onDateChange} />
</div>
);
}
}
export default DatePicker;
When I select a new date from the date picker, this.props.currentDate on the child component gets updated. This is the date that I want. However when that prop is updated, it doesn't re-render the table with the new expected data. I realize I have to update the state of the child to get the table to re-render. I am trying to do this by setting the state in the fetchData() method by setting currentDate: this.props.currentDate. But this does not work, it doesn't update the state in real time, therefore the grid doesn't re-render. I think I am missing something conceptually about react but I am not sure what. I think the datePicker component is fine, since it can send the correct date when a date is selected and this date can be passed to the table component. Can anyone tell me why this state won't update? Or better yet, what is the best way to handle the state change when this.props.currentDate updates?
EDIT: I am now able to get the state to change with
componentWillReceiveProps(nextProps, nextContext) {
if (nextProps.currentDate !== this.state.currentDate) {
this.setState({currentDate: nextProps.currentDate});
}
}
but it still won't re-render the table on update.