我有下面的示例react(v18.2)代码,它工作得很好,正如预期的那样->一旦searchParams中的p发生变化,MyComponent中的列表就会被新的数据替换。P随着用户在输入字段中的击键而改变。
const ParentComponent = ({ searchParams }) => {
const generateData = (searchParams) => {
const { p } = searchParams;
const newData = [];
for (let i = 0; i < 10; i++) {
const newItem = p + i.toString();
newData.push(newItem);
}
return newData;
};
const data = generateData(searchParams);
return (
<div>
<MyComponent data={data} />
</div>
);
};
const MyComponent = ({ data }) => (
<ul>
{data.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
然而,在我的实际组件中,generateData函数由4个for循环组成,用于创建数据。4个for循环总共循环最多(5个选项 * 4个选项 * 2个选项 * 2个选项=)80次,以生成所需的数据,例如:如下:
for (let i = 0; i < 5; i++) {
const newItem = p + i.toString()
for (let j = 0; j < 4; j++) {
newItem += j.toString()
for (let k = 0; k < 2; k++) {
newItem += k.toString()
for (let l = 0; l < 2; l++) {
newItem += l.toString()
newData.push(newItem);
}
}
}
}
我的问题:
- 如果我只在代码中添加第二个for循环(或者第三个、第四个循环,或者所有循环的组合),MyComponent中的列表不会被新数据替换,而是保留所有历史数据并将所有新数据追加到列表中。
预期行为: - MyComponent中的列表应该在新数据进入时替换旧数据,而不是将新数据追加到列表中。
我尝试了什么: - 删除for循环(使用1个for循环可以正常工作,添加第二个循环后会中断)
- 减少for循环中的选项数量(没有帮助)
- 在父级中引入useState(没有帮助)
- 将generateData函数移到组件之外(没有帮助)
- 询问ChatGPT(没有帮助-尽管它表明这可能是generateData函数中的性能问题。我可以想象,但不是用这么少量的循环-对吗?)
编辑:最小可重现的示例(我是一个初学者程序员-我不知道如何将nextjs片段添加到codepen或类似的代码-但这在我的本地主机上运行并重现错误。
'use client';
import { usePathname, useRouter } from 'next/navigation';
const generateData = (keywords: string[] = ['test', 'stack']) => {
const newData = [];
const minChunk = 2;
const maxChunk = 3;
for (let i = 0; i < keywords.length; i += 1) {
const word = keywords[i];
for (let j = 0; j < keywords.length; j += 1) {
if (i !== j) {
const nextWord = keywords[j];
for (let k = minChunk; k < maxChunk + 1; k += 1) {
const firstChunk = word.slice(0, k);
for (let l = minChunk; l < maxChunk + 1; l += 1) {
const nextChunk = nextWord.slice(-l);
const newItem = firstChunk + nextChunk;
newData.push(newItem);
}
}
}
}
}
return newData;
};
export default function ParentComponent({
searchParams,
}: {
searchParams: {
p: string;
};
}) {
const keyword = searchParams.p ?? '';
const keywordArray = keyword.split(',');
const { replace } = useRouter();
const pathname = usePathname();
if (keywordArray[keywordArray.length - 1] === '') {
keywordArray.pop();
}
const data = generateData(keywordArray);
function handleChange(term: string, paramLetter: string) {
const params = new URLSearchParams(window.location.search);
if (term) {
params.set(paramLetter, term);
} else {
params.delete(paramLetter);
}
replace(`${pathname}?${params.toString()}`);
}
return (
<div className="container mt-32">
<input
id="keyword"
placeholder="Keyword"
onChange={(e) => handleChange(e.target.value.split(' ').join(','), 'p')}
/>
<h1>Results: </h1>
<ul>
{data.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
}
1条答案
按热度按时间i86rm4rw1#
你不能在常量上使用
+=
操作,因为它是一个重新赋值。这导致了一个错误,我的假设是您的HMR设置导致它看起来像是其他问题。除此之外,你的循环工作如预期。