gpt4 book ai didi

javascript - backgroundColor 不会重新渲染 - React

转载 作者:行者123 更新时间:2023-11-30 13:49:38 26 4
gpt4 key购买 nike

我正在构建一个排序算法可视化工具。这些项目中的每一项都是 divbackgroundColor 设置为白色。 enter image description here

当算法运行时,他将 backgroundColor 设置为橙色以显示哪些项目已更改。

enter image description here

但是当我使用 setState() 重置数组时,问题发生了,因为 react 重新渲染新数组非常好,但他从未将背景颜色渲染回白色。

这是我的组件:

import React from 'react'
import './SortingVisualizer.css'
import InsertionSort from '../SortingAlgorithms/InsertionSort'

const NORMAL_COLOR = 'white';
const CHANGED_COLOR = 'red';
const AFTER_CHANGE_COLOR = 'orange';

export default class SortingVisualizer extends React.Component{

constructor(props){
super(props);

this.state = {
arrayToSort: []
};
}

componentDidMount(){
this.resetArray();
}

resetArray(){
const arrayToSort = [];
for (let i = 0; i < 200; i++) {
arrayToSort.push(this.RandomIntBetweenRange(5, 1000));
}
this.setState({ arrayToSort });
}

insertionSort(){
let sortedArrayAnim = InsertionSort(this.state.arrayToSort);
let arrayToSort = this.state.arrayToSort;
let arrayBars = document.getElementsByClassName('array-item');
let arrayBarsWithColorChanged = [];

//loop through all the animations
for (let index = 0; index < sortedArrayAnim.length; index++) {
const [i,j] = sortedArrayAnim[index];

//setTimeout(() => {
//set changed colors back to normal
if(index !== 0){
arrayBarsWithColorChanged.forEach((element, index) => {
arrayBars[element].style.backgroundColor = AFTER_CHANGE_COLOR;
});
arrayBarsWithColorChanged = [];
}

let temp = arrayToSort[i];
//change array
arrayToSort[i] = arrayToSort[j];
arrayToSort[j] = temp;

//change div bar colors, unl
if(index != sortedArrayAnim.length - 1){
arrayBars[i].style.backgroundColor = CHANGED_COLOR;
arrayBars[j].style.backgroundColor = CHANGED_COLOR;
arrayBarsWithColorChanged.push(i);
arrayBarsWithColorChanged.push(j);
}
this.setState({ arrayToSort })
//}, 10);
}
}

render() {
const {arrayToSort} = this.state;

return (
<div className="main-div">
{arrayToSort.map((value, idx) => (
<div className="array-item" key={idx} style={{height: value, backgroundColor: 'white'}}>

</div>
))}

<button onClick={() => this.resetArray()}>Generate new array</button>
<button onClick={() => this.insertionSort()}>Insertion Sort</button>
</ div>
);
}

RandomIntBetweenRange(min, max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}

最佳答案

在 React 中,您不直接操作 DOM,也不改变状态(例如 arrayToSort[i] = arrayToSort[j])。您更改模型(状态、 Prop ), View 也会相应更改。

因此,在您的情况下,您需要在状态中包含列值数组 (arrayToSort)、要交换的对数组 (sortedArrayAnim),以及一组先前更改的值 (prevChanged)。每当发生变化时, View 都会根据这些状态值进行更新。

演示(见代码注释):

const NORMAL_COLOR = 'white';
const CHANGED_COLOR = 'red';
const AFTER_CHANGE_COLOR = 'orange';

/** this function return the color **/
const getColor = (idx, prevChanged, [current]) => {
if(current && current.includes(idx)) return CHANGED_COLOR; // if it's in current changed pair [i, j]

if(prevChanged.has(idx)) return AFTER_CHANGE_COLOR; // if it was changed before

return NORMAL_COLOR;
}

class SortingVisualizer extends React.Component {
state = {
arrayToSort: [],
sortedArrayAnim: [],
prevChanged: new Set()
};

timeout = null;

componentDidMount() {
this.resetArray();
}

resetArray = () => {
clearTimeout(this.timeout);

const arrayToSort = [];
for (let i = 0; i < 50; i++) {
arrayToSort.push(this.RandomIntBetweenRange(1, 100));
}
this.setState({
arrayToSort,
sortedArrayAnim: [],
prevChanged: new Set()
});
}

animate = (sortedArrayAnim) => {
this.setState(
({
prevChanged,
arrayToSort
}) => {
if(!sortedArrayAnim.length) return { sortedArrayAnim };

const [current] = sortedArrayAnim;
const newArrayToSort = [...arrayToSort]; // clone newArrayToSort

/** flip the values according to current change [i, j] **/
newArrayToSort[current[0]] = arrayToSort[current[1]];
newArrayToSort[current[1]] = arrayToSort[current[0]];

return ({
arrayToSort: newArrayToSort,
sortedArrayAnim,
prevChanged: new Set([...prevChanged, ...current]) // add changed items to the Set
});
},
() => { // when state change is done
const { sortedArrayAnim } = this.state;

// if there are more items to change wait and call animate again
if(sortedArrayAnim.length) {
this.timeout = setTimeout(() => this.animate(sortedArrayAnim.slice(1)), 1000);
}
}
);
}

insertionSort = () => {
const sortedArrayAnim = [[1, 5], [10, 15], [20, 13], [17, 48], [20, 13], [45, 17]]; // InsertionSort(this.state.arrayToSort); // I've used a dummy array

this.animate(sortedArrayAnim);
}

render() {
const { arrayToSort, sortedArrayAnim, prevChanged } = this.state;

return (
<div className="main-div">
{arrayToSort.map((value, idx) => (
<div className="array-item" key={idx} style={{
height: `${value}vh`,
backgroundColor: getColor(idx, prevChanged, sortedArrayAnim)
}}>

</div>
))}

<button onClick={this.resetArray}>Generate new array</button>
<button onClick={this.insertionSort}>Insertion Sort</button>
</ div>
);
}

RandomIntBetweenRange(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}

ReactDOM.render(
<SortingVisualizer />,
root
);
.main-div {
display: flex;
align-items: flex-end;
justify-content: space-between;
background: black;
height: 100vh;
padding: 1vmax 1vmax 0 ;
box-sizing: border-box;
}

.array-item {
width: 1vw;
transition: height 0.3s;
}

button {
align-self: flex-start;
}

body {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

关于javascript - backgroundColor 不会重新渲染 - React,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58530676/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com