[英]React component not getting rendered each time when state changed
我正在尝试使用冒泡排序对数组进行排序,并且在排序的每个步骤中,我想呈现数组内值 position 的变化。 因此,使用 React 制作了以下算法,它在第一次渲染更改但随后停止,不渲染任何内容。 我试图控制台记录我正在渲染的数组,并且我在控制台上获得了每个排序步骤,但不知道为什么它在这里不起作用。 谁能告诉我为什么会这样? 还有什么可以做的?
注意:它工作正常并最初渲染排序数组,但后来当我添加setTimeOut
function 时它不起作用。
应用程序.js
import React, { useState } from "react";
const App = () => {
const [arrayForSort, setArrayForSort] = useState([44,2,46,11,15,34,1,7,55]);
const fetchArray = arrayForSort.map((element) => {
return <span>{element} </span>;
});
const bubbleSort = (array) => {
let newArray = [...array];
let n = newArray.length;
for (let i = 0; i < n; i++) {
for (let j = 0; j < n - i; j++) {
const myVar = setTimeout(() => {
if (newArray[j] > newArray[j + 1]) {
[newArray[j], newArray[j + 1]] = [newArray[j + 1], newArray[j]];
}
console.log(newArray); // render each step of sort
setArrayForSort(newArray); // on screen it just shows "2 44 46 11 15 34 1 7 55" the very first step of sort
}, 2000);
}
}
};
return (
<div>
<h4>Array: </h4>
<span>{fetchArray}</span>
<div>
<button
onClick={() => {
bubbleSort(arrayForSort);
}}
>
Sort
</button>
</div>
</div>
);
};
export default App;
您的代码中几乎没有问题。 2000
是一个常量值,这意味着您的所有setTimeout
会在 2 秒后一起触发。 这就是为什么你所有的console.logs
会同时出现。
其次, setTimeout
将保留setArrayForSort
的引用。 但是每次渲染后都需要一个新的参考。 如果您使用 class 组件,这可能会起作用,但对于功能组件,您需要以不同的方式思考。
这是一个有效的演示代码框链接
import React, { useEffect, useRef, useState } from "react";
const App = () => {
const [arrayForSort, setArrayForSort] = useState([44, 2, 46, 11, 15, 34, 1, 7, 55]);
const ijRef = useRef({ i: 0, j: 0 });
const [isSorting, setIsSorting] = useState(false);
const fetchArray = arrayForSort.map((element) => {
return <span key={element}>{element} </span>;
});
useEffect(() => {
if (!isSorting) return;
const ij = ijRef.current;
const i = ij.i;
const j = ij.j;
const arr = [...arrayForSort];
const n = arr.length;
let isSwapped = false;
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
isSwapped = true;
}
if (j < n - i) {
ij.j++;
} else if (ij.i < n) {
ij.j = 0;
ij.i++;
}
// This will trigger the next render
// and loop will continue until ij.i < n
setTimeout(
() => {
if (ij.i >= n) {
setIsSorting(false);
}
setArrayForSort(arr);
},
isSwapped ? 100 : 0 // delay 100ms for a successful swap
);
}, [ijRef, arrayForSort, setArrayForSort, isSorting]);
const beginSort = () => {
ijRef.current.i = 0;
ijRef.current.j = 0;
setIsSorting(true); // begin sorting
};
return (
<div>
<h4>Array: </h4>
<span>{fetchArray}</span>
<div>
<button onClick={beginSort}>Sort</button>
</div>
</div>
);
};
export default App;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.