I'm learning React by building a simple Cryptocurrency Ticker:
class Ticker extends Component {
constructor(props) {
super(props)
this.state = {
currencies: [],
limit: 12
}
}
getCurrencies = (num) => {
axios.get(`https://api.coinmarketcap.com/v1/ticker/?limit=${num}`)
.then(res => this.setState({
currencies: res.data
}));
}
componentDidMount = () => {
const { limit } = this.state;
this.getCurrencies(limit);
this.tickerTimer = setInterval(() => this.getCurrencies(limit), 10000);
}
render() {
const { currencies } = this.state;
return (
<div>
{currencies.map((currency) => {
return (
<Crypto key={currency.id} currency={currency} />
)
})}
</div>
);
}
}
getCurrencies()
makes a request and populates this.state.currencies
array.componentDidMount()
makes the initial request for the first render with the default limit of cryptocurrencies (12).setInterval()
is set in componentDidMount()
to update the data every 10 seconds as soon as the app initially renders.Everything was running smoothly until I tried to implement an Input Field to allow the user to set his own limit of displayed cryptocurrencies:
handleChange = (e) => {
this.setState({
limit: e.target.value
}, () => {
this.getCurrencies(this.state.limit);
})
}
...
render() {
....
<input onChange={this.handleChange} />
}
handleChange()
passes the input's value to this.state.limit
The thing is, since componentDidMount()
runs only once and doesn't care about the updates on the state, the limit thats set by the user is only temporary. The getCurrencies function is called from componentDidMount()
after 10 seconds, and it obviously uses the initial value that's been past originaly (12).
I tried to hook the interval in handleChange()
, but then the ticker is triggered only if the user inputs a value.
I tried doing it in render()
as well but it seems bugged.
What am I missing ?
Where could I set the Interval ?
Should I use a setInterval method to begin with ?
You just need a small change for getCurrencies
and componentDidMount
:
getCurrencies = () => {
axios.get(`https://api.coinmarketcap.com/v1/ticker/?limit=${this.state.limit}`)
.then(res => this.setState({
currencies: res.data
}));
},
componentDidMount = () => {
this.getCurrencies();
this.tickerTimer = setInterval(() => this.getCurrencies(), 10000);
}