我已经创建了这个简单的lorem ipsum生成器,它工作正常,但是当我在其中输入一个数字并快速删除该数字时,仍然显示一些输出,请注意,当我缓慢删除数字时不会发生这种情况
Generator.js
import React,{Component} from 'react';
import Output from './Output.js';
class Generator extends Component{
state = {
sentence: 0,
para: 0,
outputsentence:'',
outputpara:'',
}
sentenceHandler = async (e) => {
await this.setState({sentence: e.target.value});
if(this.state.sentence === '0' || this.state.sentence === '')
{
this.setState({outputsentence:''});
}
else{
try{
let sentence = await fetch(`https://baconipsum.com/api/?type=all-meat&sentences=${this.state.sentence}&start-with-lorem=1`);
sentence = await sentence.json();
this.setState({outputsentence:sentence});
} catch(e)
{
console.log(e);
}
}
}
paraHandler = async (e) => {
await this.setState({para: e.target.value});
if(this.state.para === '0' || this.state.para === '')
{
this.setState({outputpara:''});
}
else{
try{
console.log(e.target.value);
let paragraph = await fetch(`https://baconipsum.com/api/?type=all-meat¶s=${this.state.para}&start-with-lorem=1`);
paragraph = await paragraph.json();
this.setState({outputpara:paragraph});
} catch(e)
{
console.log(e);
}
}
}
render()
{
return(
<div className='tc'>
<h3>Number of sentences : </h3>
<input type="number" onChange={this.sentenceHandler}/>
<Output op={this.state.outputsentence} />
<h3>Number of paras : </h3>
<input type="number" onChange={this.paraHandler}/>
<Output op={this.state.outputpara} />
</div>
)
}
}
export default Generator;
Output.js
import React from 'react';
const Output = ({op}) => {
return(
<div className='tc'>
<p>
{op}
</p>
</div>
)
}
export default Output;
它工作正常,但假设我输入数字12并使用退格键快速将其删除,然后仍然显示1行或段,并且如果我先删除它的第一个字母是2,然后慢慢删除1,这不会发生。
看到它
https://wizardly-torvalds-092022.netlify.com/
最佳答案
您有比赛条件。因为异步获取/显示操作没有适当的取消机制,所以在开始另一个操作(通过将输出更改为其他内容)之后,不会阻止该操作完成。
可能有一些很好的库可以很好地处理此问题,但是这是您可以手动进行的方法。您将需要“请求ID”的概念,以便知道当前运行的操作是最新请求还是应取消的操作。
class Generator extends Component {
state = {
sentence: 0,
outputsentence: '',
currentSentenceRequestId: null,
para: 0,
outputpara:'',
currentParaRequestId: null,
}
sentenceHandler = async (e) => {
var requestId = this.state.currentSentenceRequestId++;
await this.setState({
sentence: e.target.value,
currentSentenceRequestId: requestId
});
if(this.state.sentence === '0' || this.state.sentence === '') {
this.setState({ outputsentence: '' });
} else{
try {
let sentence = await fetch(`https://baconipsum.com/api/?type=all-meat&sentences=${this.state.sentence}&start-with-lorem=1`);
sentence = await sentence.json();
// Ignore if a newer request has come in
if (this.state.currentSentenceRequestId !== requestId) {
return;
}
this.setState({
outputsentence: sentence
});
} catch(e) {
console.log(e);
} finally {
this.setState({
currentSentenceRequestId: null
});
}
}
}
// ...
}