我正在构建一个排序算法可视化工具,在返回过程中,我创建了div来表示竖条,在animatedBubbleSort()中,我在超时时交换state数组中的值,数组正在排序,但我预期的情况是,每次使用updateArray()更改状态时,.map函数都会重新呈现,但.map函数根本不会重新启动。
import React, { useState } from "react";
import "../styles/App.css";
import { Header } from "./Header";
export default function SortingVisualizer(props) {
const LOWER_BOUND = 5;
const UPPER_BOUND = 200;
const ARRAY_SIZE = 200;
const [array, updateArray] = useState(fillArrayWithRandomValues);
// returns a random number between bounds inclusive
function randomNumberBetweenBounds() {
return Math.floor(Math.random() * UPPER_BOUND) + LOWER_BOUND;
}
// fills array with random values
function fillArrayWithRandomValues() {
let tempArray = [];
for (let i = 0; i < ARRAY_SIZE; i++) {
tempArray.push(randomNumberBetweenBounds());
}
return tempArray;
}
function animatedBubbleSort() {
let tempArr = array;
let len = tempArr.length;
for (let i = 0; i < len; i++) {
for (let j = 0; j < len; j++) {
if (tempArr[j] > tempArr[j + 1]) {
let tmp = tempArr[j];
tempArr[j] = tempArr[j + 1];
tempArr[j + 1] = tmp;
setTimeout(() => {
updateArray(tempArr);
}, 300 * i);
}
}
}
}
return (
<div>
<Header bubbleSort={animatedBubbleSort} />
<div className="array-container">
{array.map((value, idx) => {
return (
<div
style={{ height: `${value * 2}px` }}
className="array-bar"
key={idx}
></div>
);
})}
</div>
</div>
);
}
6条答案
按热度按时间ha5z0ras1#
这是因为你使用数组中元素的索引作为键,React使用
key
来决定哪些元素要重新呈现;由于密钥的顺序始终相同,React不会更新任何内容。请尝试:请访问https://reactjs.org/docs/lists-and-keys.html#keys了解更多信息,具体如下:
如果项目的顺序可能会改变,我们不建议使用索引作为键。这可能会对性能产生负面影响,并可能导致组件状态问题。请查看Robin Pokorny的文章了解in-depth explanation on the negative impacts of using an index as a key。如果您选择不为列表项目分配显式键,那么React将默认使用索引作为键。
rt4zxlrg2#
其他的答案也是正确的。
尝试在键中使用唯一的值,但主要问题是
TempArray = array
将两个变量赋给同一个引用,因此,当React尝试比较array
和tempArray
时,它们将是相同的值,这不会触发重新渲染。要有效地制作数组副本,请尝试使用
tempArray = [...array]
以避免对原始数组进行不需要的更改。o4hqfura3#
TLDR:尝试更新数组(临时数组切片(0))
我为同样的问题安静地挣扎了一段时间,答案并没有解决我的问题。
如果使用modifiedState.slice(0),则会创建前置对象的副本,然后使用setState(modifiedState.slice(0))或updateArray(tempArr.slice(0))。这将强制.map-Operation重新呈现。
5vf7fwbs4#
对于遇到这个问题并且已经使用ID作为键的人,我的问题是我正在做一个双Map,但是渲染了第二个数组。我必须将键从父MapID更改为渲染的MapID,以便React可以检测到更改。
8dtrkrch5#
这并不是在所有情况下都有效,但我设法通过使用随机数作为索引来解决类似的问题。
ccgok5k56#
只需执行以下updateArray([...tempArr])即可看到效果