我正在尝试构建一个类似于此的排序可视化器:https ://clementmihailescu.github.io/Sorting-Visualizer/使用 React。
为了处理合并排序算法中每个步骤的 Canvas 更新,我尝试使用状态变量 yHeights (对应于要排序的每行的高度)并在每次调用 mergesort() 期间更新此变量的状态.
但是,我遇到了一个无限循环,我相信是因为我没有保持 render() 方法“纯”——例如,我在 render 方法期间更新状态。
如何在每次调用 mergesort() 期间重构此代码以正确更新画布绘图?我想我也许可以使用 getDerivedStateFromProps 来做到这一点,但我很难理解和使用文档来实现。
代码:
//App.js
import logo from './logo.svg';
import './App.css';
import Controls from './Controls';
import Canvas from './Canvas';
import {useState} from 'react'
var xPositions = []
function getRandomInt(max) {
return Math.floor(Math.random() * max);
}
function App() {
const [yHeights, setyHeights] = useState([])
function merge(left, right) {
let sortedArr = []; // the sorted elements will go here
while (left.length && right.length) {
// insert the smallest element to the sortedArr
if (left[0] < right[0]) {
sortedArr.push(left.shift());
} else {
sortedArr.push(right.shift());
}
}
// use spread operator and create a new array, combining the three arrays
return [...sortedArr, ...left, ...right];
}
function mergeSort(arr) {
setyHeights([arr])
const half = arr.length / 2;
// the base case is array length <=1
if (arr.length <= 1) {
return arr;
}
const left = arr.splice(0, half); // the first half of the array
const right = arr;
return merge(mergeSort(left), mergeSort(right));
}
const draw = context => {
var arrHeights = []
context.fillStyle = "rgb(0, 0, 0)";
for (var i = 0; i < 100; i+=1) {
const height = getRandomInt(500)
context.fillRect(i * 10, 0, 10, height);
xPositions.push(i*10);
arrHeights.push(height)
}
setyHeights(arrHeights);
console.log(yHeights)
};
return (
<div className="App">
<Controls />
<Canvas draw={draw} numLines={100} />
</div>
);
}
export default App;