Как создать приложение Ticker в React, используя значения по умолчанию, которые пользователь может динамически обновлять

Я изучаю React, создав простой тикер криптовалюты:

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() делает запрос и заполняет this.state.currencies массив.
  • componentDidMount() делает начальный запрос для первого рендера с лимитом криптовалют по умолчанию (12).
  • setInterval() установлен в componentDidMount() обновлять данные каждые 10 секунд, как только приложение изначально рендерится.

Все работало гладко, пока я не попытался реализовать поле ввода, чтобы позволить пользователю установить свой собственный предел отображаемых криптовалют:

handleChange = (e) => {
    this.setState({
        limit: e.target.value
    }, () => {
        this.getCurrencies(this.state.limit);
    })
}
...
render() {
    ....
    <input onChange={this.handleChange} />
}
  • handleChange() передает значение входа в this.state.limit
  • обратный вызов позволяет мне динамически обновлять пользовательский интерфейс с изменением (это то, что я видел, чтобы справиться с асинхронностью setState).

Дело в том, что, так как componentDidMount() запускается только один раз и не заботится об обновлениях состояния, ограничение, установленное пользователем, является временным. Функция getCurrencies вызывается из componentDidMount() через 10 секунд, и он, очевидно, использует начальное значение, которое прошло оригинально (12). Я пытался подключить интервал в handleChange(), но тикер срабатывает только в том случае, если пользователь вводит значение. Я пытался сделать это в render() как хорошо, но, похоже, прослушивается.

  • Мне бы хотелось, чтобы мое приложение отображало и обновляло данные нужного количества криптографических данных, независимо от того, изменяет ли пользователь количество, которое он хочет отобразить. Если он изменит значение по умолчанию, я не хочу, чтобы оно было перезаписано чем-то другим, кроме него самого.

Что мне не хватает?

Где я могу установить интервал?

Должен ли я использовать метод setInterval для начала?

2 ответа

Решение

Вам просто нужно небольшое изменение для getCurrencies а также 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);
}

Читайте из состояния каждый раз, а не только один раз.

componentDidMount = () => {
    this.getCurrencies(limit);
    this.tickerTimer = setInterval(() => {        
        const { limit } = this.state;
        this.getCurrencies(limit);
    }, 10000);
}
Другие вопросы по тегам