Вот что я могу вам предложить:
import React, { Component } from "react";
import { render } from "react-dom";
import React, { useState, useEffect } from "react";
const Dummy2 = () => {
const [arr, setArr] = useState([]);
const [length, setLength] = useState(10);
const [reverseIndex, setReverseIndex] = useState(0);
const [didMount, setDidMount] = useState(true);
const [shouldReverseArray, setShouldReverseArray] = useState(true);
useEffect(() => {
generateArray();
}, [length]);
useEffect(() => {
// After clicking on 'reverse' button, reverseIndex is edited. Thus this effect is triggered because it listen to 'reverseIndex'. DidMount is here to prevent triggering the effect when the component is mounted
if (!didMount) {
if (shouldReverseArray && reverseIndex < length / 2) {
setTimeout(() => reverseArray(), 1000);
} else {
shouldReverseArray = setShouldReverseArray(false);
setReverseIndex(0);
}
} else {
setDidMount(false);
}
}, [reverseIndex]);
const generateArray = () => {
const temp = [];
for (let i = 0; i < length; i++) {
temp.push(i + 1);
}
setArr(temp);
};
const handleLength = e => {
setLength(e.target.value);
};
const reverseArray = () => {
const temp = Object.assign([], arr); // Make a copy of your state because it is not mutable
const tempStart = temp[reverseIndex];
const tempEnd = temp[length - tempStart];
temp[reverseIndex] = tempEnd;
temp[length - tempStart] = tempStart;
setArr(temp); // Set the new arr
setReverseIndex(prevState => ++prevState); // Set the new index
};
const printArray = () => {
console.log(arr);
};
const maxVal = Math.max(...arr);
return (
<div>
<div className="array-container" style={{ height: "50%" }}>
{arr.map((value, idx) => (
<div
className="array-element"
key={idx}
style={{
height: `${((value * 100) / maxVal).toFixed()}%`,
width: `calc(${100 / length}% - 2px)`,
margin: "0 1px",
display: "inline-block",
backgroundColor: "black",
color: "white"
}}
>
{value}
</div>
))}
</div>
<div>
<button onClick={() => generateArray()}>New array</button>
<button onClick={() => {setShouldReverseArray(true); reverseArray()}}>Reverse</button>
<button onClick={() => printArray()}>Print array</button>
</div>
<div className="slider-container">
1
<input
type="range"
min="1"
max="100"
onChange={e => handleLength(e)}
className="slider"
id="myRange"
/>
100
</div>
{length}
</div>
);
};
export default Dummy2;
render(<Dummy2 />, document.getElementById("root"));
Вот Stackblitz repro .
Обратите внимание, что при изменении размера вашего массива вести себя странно, я не знаю, исходит ли это из моего кода или вашего, я попытаюсь выяснить.
Кроме того, если вам не нужно отображать каждое изменение, вы можете использовать .reverse()
это было бы действительно проще.
[Edit]: Хорошо, ошибка произошла из-за того, что reverseIndex не сбрасывается. Я отредактировал код, чтобы добавить состояние shouldReverseArray. Я вызываю это в событии onClick в jsx. Довольно грязно, но я не могу здесь думать ни о чем другом. Надеюсь, это поможет:)