reactjs - 在 React 中渲染数组排序的每次迭代
问题描述
我正在尝试在 react 中构建一个简单的应用程序,该应用程序需要一个未排序的数组(this.state.dataset),然后插入对其进行排序并呈现排序过程的每次迭代。
因为 React 是在每次数组更改后异步放置一个 setstate 不起作用。任何想法如何解决这个问题?
我可以通过在每个数组更改后简单地退出函数然后渲染它,然后使用更新的数组重新启动冒泡排序来使用冒泡排序来做到这一点。但是我不能让这种方法在这里工作。我知道效率很低,抱歉我是新手..
render() {
return (
<div className="buttons">
<button onClick={this.sort}>Insertion Sort</button>
</div>
);
}
sort(e) {
this.myInterval = setInterval(() => {
let arr = this.insertionSort();
this.setState({
dataset: arr,
});
}
}, 1000);
insertionSort(e) {
let inputArr = this.state.dataset
let length = inputArr.length;
for (let i = 1; i < length; i++) {
let key = inputArr[i];
let j = i - 1;
while (j >= 0 && inputArr[j] > key) {
inputArr[j + 1] = inputArr[j];
j = j - 1;
return inputArr //Added by me to stop loop and render (probably wrong solution)
}
inputArr[j + 1] = key;
return inputArr //Added by me to stop loop and render (probably wrong solution)
}
return inputArr;
};
(我的 render() 方法中有 this.state.dataset 渲染,但为简洁起见排除在外
解决方案
一种可能的解决方案可能是将迭代数组所需的值存储在状态中。在每次修改时,您都可以更新状态并从排序函数返回。
因为 React 在每次数组更改后异步放置一个 setState 是行不通的。任何想法如何解决这个问题?
setState 函数采用状态更新时调用的第二个回调参数。这意味着您可以有效地将状态更新视为同步的。
这是使用此方法的工作实现:
(这是用 React Native 编写的,但逻辑与常规 React 相同)
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
i: 1,
j: 0,
data: [...initialData],
};
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={({ item }) => <Text>{item}</Text>}
/>
<Button title="Sort" onPress={this.sort} />
<Button title="Reset" onPress={this.reset} />
</View>
);
}
sort = () => {
const { i, j, key, data: oldData } = this.state;
const nextSort = () => setTimeout(this.sort, 500);
if (i == oldData.length) {
return;
}
const data = [...oldData];
const value = key ? key : data[i];
if (j >= 0 && data[j] > value) {
data[j + 1] = data[j];
this.setState({ j: j - 1, data, key: value }, nextSort);
return;
}
data[j + 1] = value;
this.setState({ i: i + 1, j: i, data, key: undefined }, nextSort);
};
reset = () => this.setState({ data: [...initialData], i: 1, j: 0, key: undefined });
}
在现有实现中值得一提的最后一件事是状态的突变。当您的状态中有一个数组时,您无法修改该数组,因为这会在您调用 setState 时引起问题。
例如,您的变量dataSet
存储在状态中。然后,您使用以下方法设置inputArr
状态值的引用dataSet
:
let inputArr = this.state.dataset
当您现在调用inputArr[j + 1] = inputArr[j];
原始数组(在您的状态)时会更新。如果你用inputArr
React 调用 setState ,它将与dataSet
. 当您修改后dataSet
,值将匹配inputArr
,这意味着状态不会更新。
您可以在我的解决方案中看到此问题的解决方法,其中我将 dataSet 复制到一个新数组中:
const data = [...oldData]
这将阻止您所在州的数组更新。
推荐阅读
- python - server = ThreadingHTTPServer((host, port), Handler) TypeError: __init__() 缺少 1 个必需的位置参数:'server'
- autodesk-forge - 在伪造查看器中找不到分组元素
- liquid - 删除 Liquid 模板中字符串的第一行
- c# - 使用 Klarna 创建新订单的错误请求
- java - 当我的当前位置在谷歌地图中移动时更新距离的任何代码
- android - 如果我在 firebase 身份验证中有很多冗余匿名用户,可以吗?
- javascript - 无法将事件处理程序附加到 ClassicEditor
- php - 我想用 Ajax 每隔几秒执行一次这个脚本而不重新加载页面
- python - 即使您已退出 ssh 会话,也每隔几天运行一次进程
- python - main() 缺少 1 个必需的位置参数:'self'