在 React 中,我应该如何将开始经过的时间传递给秒表组件并从该经过的时间启动正在运行的增量器?



>我可以根据拉取的开始时间显示静态经过的秒数,但我无法获取经过的秒数以继续计数。我知道我可能不应该使用这些道具来更新孩子的状态,但即使没有它,我也无法让它工作并尝试将其作为一种解决方法。任何帮助,不胜感激。

父级如下所示:

class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
elapsedSeconds: -1
};
this.changeElapsedSecondsParent = this.changeElapsedSecondsParent.bind(this);
}
changeElapsedSecondsParent(newElapsed) {
this.setState({
elapsedSeconds: newElapsed
});
}
render() {
const { elapsedSeconds } = this.state;
return (
<div>
<Stopwatch 
elapsedSeconds={elapsedSeconds} 
changeElapsed={this.changeElapsedSecondsParent}
/>
</div>
);
}
}

儿童秒表看起来像这样:

const formattedSeconds = (sec) =>
~~(sec / 60) +
':' +
('0' + sec % 60).slice(-2)

export class Stopwatch extends React.Component {
constructor(props) {
super(props);
this.state = {
secondsElapsed: -1,
laps: [],
lastClearedIncrementer: null
};
this.incrementer = null;
this.handleStartClick = this.handleStartClick.bind(this);
this.handleStopClick = this.handleStopClick.bind(this);
this.handleResetClick = this.handleResetClick.bind(this);
this.handleLapClick = this.handleLapClick.bind(this);
}
componentDidMount() {
if(this.state.secondsElapsed < 0) {
const getElapsedTime = async () => {
try{
const response =  await fetch(`api url`);
if(response.ok){
let jsonResponse = await response.json();
/* start getting seconds elapsed since start */
let currentServerTime = new Date(jsonResponse[0].currentTimeStamp).getTime() /1000;
let currentD = Math.floor(new Date().getTime()/1000);
let deltaDate = (currentServerTime-currentD);
let raceStartTime = new Date(jsonResponse[0].startTime).getTime()/1000 - deltaDate;
let secondsElapsedSinceStart = currentD - raceStartTime;
/* end getting seconds elapsed since start */
this.props.changeElapsed(secondsElapsedSinceStart);
}
}
catch(error){
console.log(error);
}
}
getElapsedTime();
let newElapsed = this.props.elapsedSeconds;
this.incrementer = setInterval( () =>
this.setState({
secondsElapsed: newElapsed + 1
})
, 1000);
} else {
this.incrementer = setInterval( () =>
this.setState({
secondsElapsed: this.state.secondsElapsed + 1
})
, 1000);
}
}
handleStartClick() {
/* start post request */
const pushTime = async () => {
try {
const response = await fetch('apiurl', {
method: 'POST',
body: JSON.stringify({"startTime": "'2018-08-26 16:57:09'"})
})
if(response.ok){
const jsonResponse = await response.json();
return jsonResponse;
}
throw new Error('Request failed!');
} catch(error) {
console.log(error);
}
}
pushTime();
}
handleStopClick() {
clearInterval(this.incrementer);
this.setState({
lastClearedIncrementer: this.incrementer
});
}
handleResetClick() {
clearInterval(this.incrementer);
this.setState({
secondsElapsed: 0,
laps: []
});
}
handleLapClick() {
this.setState({
laps: this.state.laps.concat([this.props.elapsedSeconds])
})
}
render() {
return (
<div className="stopwatch">
<h1 className="stopwatch-timer">{formattedSeconds(this.state.secondsElapsed)}</h1>
{(this.props.elapsedSeconds === 0 ||
this.incrementer === this.state.lastClearedIncrementer
? <Button className="start-btn" onClick={this.handleStartClick.bind(this)}>start</Button>
: <Button className="stop-btn" onClick={this.handleStopClick.bind(this)}>stop</Button>
)}
{(this.props.elapsedSeconds !== 0 &&
this.incrementer !== this.state.lastClearedIncrementer
? <Button onClick={this.handleLapClick.bind(this)}>lap</Button>
: null
)}

{(this.props.elapsedSeconds !== 0 &&
this.incrementer === this.state.lastClearedIncrementer
? <Button onClick={this.handleResetClick.bind(this)}>reset</Button>
: null
)}
<ul className="stopwatch-laps">
{ this.state.laps.map((lap, i) =>
<li className="stopwatch-lap"><strong>{i + 1}</strong>/ {formattedSeconds(lap)}</li>)
}
</ul>
</div>
);
}
}
const Button = (props) =>
<button type="button" {...props} className={"btn " + props.className } />;

我发现在构造函数中定义常量更容易,例如:

this.deltaTime = null;

然后我创建了一个 changeDeltaTime 函数:

changeDeltaTime(newTime) {
this.deltaTime = newTime
}

最后,我在 promise 中更新了 deltaTime,并在 componentDidUpdate(( 生命周期方法中的响应之后更新了该 deltaTime。

await this.changeDeltaTime(deltaDate);

在渲染中,我等待通过父传递的道具解决承诺

return !this.props.finishedGet ? <span>Waiting on fetch...</span> : (this.renderStopwatch(this.state.time))

这也涉及要创建的 renderStopwatch 函数,但它基本上只包含承诺解决后应该创建的内容。

最新更新