我已经在react中创建了一个简单的计时器应用程序,您可以输入一个数字并开始倒计时。仅仅为了#34;学习反应" - 目的我实现了一个API来存储已设置的计时器。他们在componentDidMount上阅读。您可以使用按钮逐个删除它们。问题:启动计时器是在一个不同的组件,并不知道" RecentTimers"零件。我不确定如何通过反应正确地做到这一点。
这是关心实际计时器的组件:
import React, { Component } from 'react';
import Axios from 'axios';
import ProgressBar from './ProgressBar';
import Input from './Input';
import Message from './Message';
import RecentTimers from './RecentTimers';
export default class Timer extends Component {
constructor(props) {
super(props);
this.state = {
running: false,
secsStart: 0,
secsRemaining: 0
};
this.startTimer = this.startTimer.bind(this);
this.tick = this.tick.bind(this);
}
startTimer(startValue) {
this.setState({
running: true,
secsStart: startValue,
secsRemaining: startValue
});
this.timer = setInterval(this.tick, 1000);
this.saveTimer(startValue);
}
saveTimer(startValue) {
Axios.post('http://rest.learncode.academy/api/svartberg/timers', {
timestamp: + new Date(),
seconds: startValue
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
UIkit.notification({
message: 'Couldn\'t save the timer.<br />' + error,
status: 'danger',
pos: 'bottom-right'
});
});
}
tick() {
if (this.state.running) {
if (this.state.secsRemaining > 0) {
this.setState({
secsRemaining: this.state.secsRemaining - 1
});
} else {
this.setState({
running: false
});
clearInterval(this.timer);
}
}
}
renderProgress() {
return this.state.secsRemaining <= 0
? <Message>Der Timer ist abgelaufen.</Message>
: <ProgressBar
secsRemaining={this.state.secsRemaining}
secsStart={this.state.secsStart}
/>;
}
render() {
return (
<div className="uk-container uk-container-center uk-margin-large-top uk-margin-large-bottom">
<h1 className="uk-text-center">Simple Timer</h1>
<Input startFunc={this.startTimer} status={this.state.running} />
<div className="uk-text-center uk-margin-top">
<span className="uk-text-lead">{this.state.secsRemaining}</span>{' '}
seconds left.
</div>
{ this.renderProgress() }
<RecentTimers />
</div>
);
}
}
这是关注最近使用的计时器列表的组件:
import React, { Component } from 'react';
import Axios from 'axios';
import UIkit from 'uikit';
import Icons from 'uikit/dist/js/uikit-icons';
UIkit.use(Icons);
export default class RecentTimers extends Component {
constructor() {
super();
this.state = {
loading: true,
recentTimers: []
};
}
componentDidMount() {
this.getRecentTimers();
}
getRecentTimers() {
this.setState({ loading: true });
Axios.get('http://rest.learncode.academy/api/svartberg/timers')
.then((response) => {
this.setState({
loading: false,
recentTimers: response.data.reverse()
});
})
.catch(function (error) {
UIkit.notification({
message: 'Couldn\'t fetch recent timers.<br />' + error,
status: 'danger',
pos: 'bottom-right'
});
});
}
deleteRecentTimerItem(item) {
Axios.delete('http://rest.learncode.academy/api/svartberg/timers/' + item.id)
.then((response) => {
this.getRecentTimers();
UIkit.notification({
message: 'Item deleted',
status: 'success',
pos: 'bottom-right'
});
})
.catch(function (error) {
UIkit.notification({
message: 'Couldn\'t delete timer with ID ' + item.id + '.<br />' + error,
status: 'danger',
pos: 'bottom-right'
});
});
}
renderRecentTimerItems() {
if (this.state.loading) {
return <div className="uk-text-center"><span data-uk-spinner={''} /></div>;
} else {
return this.state.recentTimers.length > 0
? this.state.recentTimers.map((item, index) => (
<li key={index}>
{new Date(item.timestamp).toLocaleDateString()} - {new Date(item.timestamp).toLocaleTimeString()} <span className="uk-margin-small-left uk-margin-small-right">|</span> {item.seconds} Secs.
<span onClick={this.deleteRecentTimerItem.bind(this, item)} className="uk-float-right" style={{lineHeight: 'normal'}} data-uk-icon="icon: close"></span>
</li>
))
: <p>No recent timers.</p>;
}
}
render() {
return (
<div>
<hr />
<div className="uk-card uk-card-default uk-card-body">
<h3 className="uk-card-title uk-text-center">Recent Timers</h3>
<ul className="uk-list uk-list-divider">
{ this.renderRecentTimerItems() }
</ul>
</div>
</div>
)
}
}
我不知道如何告诉我最近的计时器组件它需要更新,因为新计时器已启动,我想在我最近的计时器列表中找到该计时器。
答案 0 :(得分:1)
在你的<RecentTimers timer={this.state.timer}>
的道具中传递计时器对象this.state.timer可以在你启动计时器时更新,并且只要添加了一个新的计时器,就可以使用componentWillRecieveProps来更新RecentTimer组件的状态在计时器列表中。
每次更新组件后,都会调用函数。
1.componentWillReceiveProps()
2.shouldComponentUpdate()
3.componentWillUpdate()
4.render()
5.componentDidUpdate()
您可以使用
componentWillReceiveProps(nextProps) {
if(nextProps.timer){
let recentTimer = this.state.recentTimers;
this.setState({
recentTimers : recentTimers.push(nextProps.timer);// this update your timers, But wont re-render the component.
});
//or save the timer
}
}
或者使用componentWillUpdate,因为此方法将重新渲染您的组件,
componentWillUpdate(nextProps , nextState){
//Code goes here.
}
有关状态处理的更多信息,您可以看到此blog。
谢谢,