В компоненте хочу реализовать таймер, по истечении которого надо сделать запрос. Пошуршал по гугглу и стеку примеры таймеров, прикрутил свое. Получилось следующее:
export default class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
secondsRemaining: 0
}
}
componentDidUpdate(prevProps, prevState) {
let {secondsRemaining} = prevState;
if (secondsRemaining === 0) {
// REQUEST
} else {
this.interval = setInterval(this.tick, 1000);
}
}
handleItemClick = () => {
this.setState({
activeItem: itemIndex,
secondsRemaining : data.time && data.time
});
};
tick = () => {
this.setState({secondsRemaining: this.state.secondsRemaining - 1});
if (this.state.secondsRemaining <= 0) {
clearInterval(this.interval);
}
};
}
По клику на айтем меню задействуется хендлер handleItemClick
, который сетит в стейт secondsRemaining
в секундах(например 60 секунд). Далее срабатывает didUpdate
и условие таково, что когда secondsRemaining
будет равно нулю, то надо выполнить запрос, если нет, ты с интервалом в 1 секунду методом SetInterval
мы отсчитываем время. Это работает,но не совсем так как надо. Он доходит до 0 и продолжает отнимать -1,-2,-3 и так о бесконечности. Какой-то косяк в моей логике,но я не пойму какой. Подскажите пожалуйста
componentDidUpdate(prevProps, prevState) {
let {secondsRemaining} = prevState;
if (secondsRemaining === 0) {
// REQUEST
} else {
this.interval = setInterval(this.tick, 1000);
}
}
Метод componentDidUpdate
вызывается каждый раз, как у вас срабатывает апдейт компонента, даже когда вы уже запустили таймер, то есть после каждого вызова таймера, вызывается этот метод, где проверяется условие, которое снова срабатывает ( таймер обновляется, правда старый таймер никуда не исчезает )
Поэтому в итоге у вас куча таймеров в памяти = утечка памяти
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
secondsRemaining: 100
};
}
componentDidUpdate(prevProps, prevState) {
let { secondsRemaining } = prevState;
if (secondsRemaining === 0) {
// REQUEST
} else if (!this.interval) { // только если еще нет таймера
this.interval = setInterval(this.tick, 10);
}
}
componentWillUnmount() {
// обязательно при анмаунте удаляем таймер
clearInterval(this.interval);
this.interval = undefined;
}
handleItemClick = () => {
this.setState({
secondsRemaining: 100
});
};
tick = () => {
this.setState({ secondsRemaining: this.state.secondsRemaining - 1 });
if (this.state.secondsRemaining <= 0) {
clearInterval(this.interval);
this.interval = undefined;
}
};
render() {
return (
<div>
<div>{this.state.secondsRemaining}</div>
<button onClick={this.handleItemClick}>click</button>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<MyComponent />, rootElement);
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Наткнулся на сайте Хоббита на такой прелестный эффект, который я обычно встречал в играх
у меня есть две функции getDep() и getRate(), и проверка(цикл), где getRate() не должен превышать getDep(), в общем do срабатывает два раза при вводе большего...
С сервлета на клиент необходимо отправить торрент-файлВ JS не силён
Мне нужно изменить обе строки в html, но с помощью innerHTML получается изменить лишь одну строку (ту, где единица написана)