I currently have a column in a react-bootstrap-table-next table that displays an expiration date. Here's how I define the column:
const columns = [{
...
}, {
dataField: 'expiresAt',
text: 'Expires',
formatter: timestampFormatter
}];
(I replaced the other columns with ...
for brevity.)
And here's the timestampFormatter function:
function timestampFormatter(cell, row) {
if (cell == null) {
return cell;
} else {
return (moment(cell).utcOffset(cell).local().format('llll'));
}
}
Here's an example of what one cell in this column looks like now:
I'd like to replace these cells with a countdown that shows the number of days, hours, and minutes (and seconds if less than a minute is left) until expiry. I can certainly write the code to create a string with this. But I don't see how to get the cells in this column to update every second.
I could replace timestampFormatter
with something like this:
function countdownFormatter(cell, row) {
return (
<Countdown expires={cell} />
);
}
...and calculate the countdown string inside the Countdown component's render method. But since the components' props would never change, they wouldn't re-render.
I could do something like this:
function countdownFormatter(cell, row) {
countdownString = countdownFromExpiration(cell);
return (
<Countdown countdown={countdownString} />
);
}
But then I don't see how to arrange the countdownFormatter functions to all get called every second.
Code Maniac's comment on my question suggesting using setTimeOut gave me what I needed to figure the rest out for myself. I did create a Countdown component as I considered in my question. Here's the code I came up with:
class Countdown extends Component {
state = {
timeRemainingString: getTimeRemainingString(this.props.expires)
};
componentDidMount() {
this.updateState();
}
updateState() {
this.setState({ timeRemainingString:
getTimeRemainingString(this.props.expires) });
this.timeout = setTimeout(() => { this.updateState() }, 1000);
}
componentWillUnmount() {
clearTimeout(this.timeout);
};
render() {
return ( this.state.timeRemainingString );
}
}