我有以下React代码:
import { useState } from 'react';
import './App.css';
import Layout from './components/Layout';
interface WordsPayload {
listedwords: string[]
}
function App() {
const [word, setWord] = useState({
wordValue: ""
});
const [words, setWords] = useState<string[]>([]);
const handleWordChange = (event: { target: { name: any; value: any; }; }) => {
setWord({ ...word, [event.target.name]: event.target.value });
};
const handleWordSubmit = (event: { preventDefault: () => void; }) => {
event.preventDefault();
setWords([...words, word.wordValue as string]);
setWord({ wordValue: "" });
};
const handleSubmit = async (event: { preventDefault: () => void; }) => {
event.preventDefault();
const jsnWords: WordsPayload =
{
listedwords: words
}
const findAnagrams = await fetch('http://localhost:3000/findanagrams', {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify(jsnWords)
});
const anagramsFound = await findAnagrams.json();
console.log(anagramsFound);
return findAnagrams;
};
return (
<Layout>
<section className="container">
<div className="flex-1 space-y-4">
<h1 className="text-4xl font-bold">
Anagram Finder
</h1>
<p className="max-w-xl leading-relaxed">
Type words consisting of only alphanumeric characters
into the text box. When you finish a word click "Add"
After you finish adding words click submit.
</p>
<div className="items-center justify-center">
<button onClick={handleSubmit}>
Submit
</button>
</div>
</div>
<form onSubmit={handleWordSubmit}>
<div className="mb-6">
<label className="block mb-2">Type word here</label>
<input
type="text"
name="wordValue"
placeholder="Name"
value={word.wordValue}
onChange={handleWordChange}
/>
</div>
<button type="submit" className="dark:focus:ring-blue-800">Add Word</button>
</form>
</section>
<section className="container">
<div className="flex-1 space-y-4"></div>
{words.map(function(d, idx){
return (<span key={idx}>{d}</span>)
})}
</section>
</Layout>
)
}
export default App
我有一个文本框,在按下按钮时,它将输入的单词推送到words
中,这是一个useState数组。这是它在操作中的样子:
我修改了handleWordSubmit
,允许一次向words
useState数组添加几个单词,方法是在,
值处分隔输入字符串,并一次推送所有这些数组值。
现在它看起来像这样:
const handleWordSubmit = (event: { preventDefault: () => void; }) => {
event.preventDefault();
if (word.wordValue.includes(',')) {
const wordParsed = word.wordValue.split(',');
for (const wordParsedIndividual in wordParsed) {
const wordStrippedMulti = wordParsed[wordParsedIndividual].replace(/[^\w\s!?]/g, '');
console.log(wordStrippedMulti);
setWords([...words, wordStrippedMulti as string])
}
} else {
const wordStrippedSingle = word.wordValue.replace(/[^\w\s!?]/g, '');
setWords([...words, wordStrippedSingle as string]);
}
setWord({ wordValue: "" });
};
所以我认为这会将字符串分离到,
s处的数组中,循环数组,并将每个字符串推送到words
useState数组。但它没有......这是发生的事情:
注意,字符串在,
s处被正确分隔,并且代码确实循环了数组中的每一项,因为它们被成功地打印到控制台。问题是实际上只有最后一项被添加到words
useState数组中。那么为什么不是所有拆分的字符串数组项都被添加到words
中呢?
3条答案
按热度按时间enyaitl31#
因为setState是异步的,可以这样修复
eqzww0vc2#
这是因为setState的异步行为。
这意味着你的
setWords
在这里是async
,你在一个循环中使用它。这就是为什么它只设置循环的最后一个迭代值。因此,只需将if块逻辑更改为:
了解有关setState async行为的更多信息:https://stackoverflow.com/a/36087156/5939058
gijlo24d3#
setWords不应该在for循环中使用,因为它不是一个立即命令,并且会有延迟。
如文档中所述
单词不会有更新的值,这就是它只显示最后插入的元素的原因。相反,您可以维护一个变量,并在循环结束执行时将其添加到状态中。