Set styles dynamically after render - react - reactjs

I currently supported my use case via componentDidMount. It worked for one time render. But soon I had to re-render the component i.e. build rows and cols again and hence to re-apply the marginLeft styles (in componentDidMount). I am not sure how to do that ?
Below is the code for the component in concern. Child graph component is a pure presentational component(read stateless).
var React = require('react');
var ReactDOM = require('react-dom');
var Graph = require('./graph');
var noOfLines, difference;
var _ = require('lodash');
module.exports = React.createClass({
displayName: 'Rules graph container',
propTypes: {
data: React.PropTypes.arrayOf(React.PropTypes.object),
lineAttributes: React.PropTypes.object,
handleNext: React.PropTypes.func,
handlePrevious: React.PropTypes.func,
pagination: React.PropTypes.object
},
getRows(n, d, lineHeight){
var rows = [], columns = [];
for (var i = n; i > 0; i--){
var isLast = (i === 1);
rows.unshift(
<div key={i} className='y-line' style={{height: lineHeight, marginTop: isLast ? (lineHeight / 2) : 0}}>
<div className='amt'>{ d + d * (n - i) }</div>
</div>
);
}
return rows;
},
buildCols(leftMargins){
const {data, lineAttributes} = this.props;
var cols = [];
for ( var i = 0; i < data.length; i++){
var height, isFirst;
if (data[i].val === lineAttributes.maxValue){
height = 100;
} else {
height = (data[i].val / lineAttributes.maxValue) * 100;
}
if (i === 0){
isFirst = true;
}
const button = `column_button_${i}`, name = _.startCase(data[i].name);
cols.push(
<div key={i} className={ isFirst ? 'first active column' : 'column'} style={{ height: `${height}%`, top: `${100 - height}%`, marginRight: '100px' }}>
<div className='count'>{data[i].val}</div>
<div className='column_button' style={{marginLeft: leftMargins && -leftMargins[i]}} ref={node => this[button] = node}><span className='event_label'>{name}</span></div>
</div>
);
}
return cols;
},
render(){
const {noOfLines: n, difference: d, lineHeight} = this.props.lineAttributes;
const rows = this.getRows(n, d, lineHeight), cols = this.buildCols();
return (
<div>
{n ? (
<Graph rows={rows} graphHeightPad={lineHeight / 2} cols={cols} pagination={this.props.pagination} />
) : null}
</div>
);
},
componentDidMount(){
const leftMargins = [];
for (var i = 0; i < this.props.data.length; i++){
var button = `column_button_${i}`;
var width = this[button].offsetWidth;
leftMargins.push(width / 4);
}
const cols = this.buildCols(leftMargins);
this.setState({cols}); // Intentional re-render
}
});

i understand that you want call the same function when re-render
what about componentDidUpdate()
do(){
const leftMargins = [];
for (var i = 0; i < this.props.data.length; i++){
var button = `column_button_${i}`;
var width = this[button].offsetWidth;
leftMargins.push(width / 4);
}
const cols = this.buildCols(leftMargins);
this.setState({cols}); // Intentional re-render
}
componentDidMount(){ this.do(); }
componentDidUpdate(){ this.do(); }

Related

create linked list in React - Expanding on the React Tic-Tac-Toe Tutorial

I'm trying to expand on the official react Tic-Tac-Toe tutorial: https://reactjs.org/tutorial/tutorial.html#completing-the-game by creating a linked list to search for the win condition. However, I am having issues accessing the information. Does anyone know where I'm going wrong? I keep getting undefined with my console.log on line 138
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
function Square(props) {
return (
\<button className="square" onClick={props.onClick}\>
{props.value}
{props.rightmiddle}
{props.righttop}
{props.rightbottom}
{props.lefttop}
{props.leftbottom}
{props.top}
{props.bottom}
\</button\>
);
}
class Board extends React.Component {
renderSquare(i) {
return (
\<Square
value={this.props.squares\[i\]}
rightmiddle = {null}
righttop = {null}
rightbottom = {null}
leftmiddle = {null}
lefttop = {null}
leftbottom = {null}
top = {null}
bottom = {null}
onClick={() =\>
this.props.onClick(i)
}
/\>
);
}
forloop(x){
const numcolumns = 3;
const options = [];
for (let i = 0; i < numcolumns; i++) {
options.push(this.renderSquare(i + x));
}
return (
<div className="board-row">
{options}
</div>
)
}
render() {
const numrows = 3;
const linklistTRow = [];
const linklistBRow = [];
const linklistMRow = [];
const rows = [];
for(let i = 0; i < numrows; i++)
{
rows.push(this.forloop(i*numrows));
if (i === 0) { linklistTRow.push(rows[0])};
if (i === 1) { linklistMRow.push(rows[1])};
if (i === 2) { linklistBRow.push(rows[2])};
};
return (
<div> {rows} </div>
);
}
}
class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
history: \[{
squares: Array(9).fill(null),
}\],
stepNumber: 0,
xIsNext: true,
};
}
handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history\[history.length - 1\];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares\[i\]){
return;
}
squares\[i\] = this.state.xIsNext ? 'X' : 'O';
this.setState({
history: history.concat(\[{
squares: squares,
}\]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext,
});
}
jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: (step % 2) === 0,
});
}
render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}>
<button onClick = {() => this.jumpTo(move)}>{desc}
</button>
</li>
);
});
let status;
if (winner) {
status = 'Winner: ' + winner;
}
else {
status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div className="game">
<div className="game-board">
<Board
squares = {current.squares}
onClick={(i) => this.handleClick(i)}
log = {console.log(this.props.value)}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
</div>
);
}
}
// ========================================
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(\<Game /\>);
function calculateWinner(squares) {
const lines = \[
\[0, 1, 2\],
\[3, 4, 5\],
\[6, 7, 8\],
\[0, 3, 6\],
\[1, 4, 7\],
\[2, 5, 8\],
\[0, 4, 8\],
\[2, 4, 6\],
\];
for (let i = 0; i \< lines.length; i++) {
const \[a, b, c\] = lines\[i\];
if (squares\[a\] && squares\[a\] === squares\[b\] && squares\[a\] === squares\[c\]) {
return squares\[a\];
}
}
return null;
}
I have been trying to use props.value to call the square number (0 to 8) however, this is showing undefined results.

Is there a good way to make a input responsive to two different things?

I have made two components, the MoveDiv component consists of a resizable div and an input. when you drag the slidebar the div will grow and shrink. The input changes as well as the div grows. Now we can also whrite in the input, and the resizable div will change as well. The other component generates four of these components. the smaller components also react to each other. I could not do this with only one state. I had to do a lot of stuff but I think it can be done better.
import React, { useState, useRef, useMemo, useReducer } from 'react'
import MoveDiv from './TestMoveDiv'
const templateTime = (time) => {
let hour = Math.floor(time)
let min = Math.round((time - Math.floor(time))*60)
hour = hour < 10 ? '0' + hour.toString() : hour.toString()
min = min < 10 ? '0' + min.toString() : min.toString()
return hour + ':' + min
}
const TestMove = () => {
const [moveDiv, setMoveDiv] = useState([
{height: 100, id: 1},
{height: 100, id: 2},
{height: 100, id: 3},
{height: 100, id: 4},
])
const getTime = (ID) => {
if (moveDiv){
let time = 0;
let i = 0;
while ( ID >= moveDiv[i].id ) {
time += moveDiv[i].height
i++
}
time = 3 + time*(23-3)/400
times.current[ID-1] = templateTime(time)
return;
}
return;
}
const times = useRef(["08:00","13:00","18:00","23:00"])
const currentId = useRef(0)
const onMouseMove = ({movementY}) => {
if (currentId.current !== 0) {
setMoveDiv((prev) => (prev.map(pre => pre.id == currentId.current ? {...pre, height: pre.height + movementY} : pre)))
changeOtherHeight(movementY)
getTime(currentId.current)
}
}
const changeOtherHeight = (movementY) => {
setMoveDiv(prev => (prev.map((pre => (pre.id === (currentId.current+1) ? {...pre, height: pre.height - movementY} : pre)))))
}
return (
<div onMouseUp={() => currentId.current = 0} onMouseMove={onMouseMove}>
{moveDiv.map((mov) => (
<MoveDiv
key={mov.id}
height={mov.height}
id={mov.id}
currentId={currentId}
times={times.current[mov.id-1]}
setMoveDiv={setMoveDiv}
getTime={getTime}
moveDiv={moveDiv}
/>))}
</div>
)
}
export default TestMove
import React, {useState, useRef, useEffect} from 'react'
import TimeInput from 'react-time-input'
import "../index.css"
const NoTemplateTime = (time) => {
console.log(time.split(":")[0])
let hour = parseInt(time.split(":")[0])
let min = parseInt(time.split(":")[1])
min = min/60*100
return hour + min/100
}
const MoveDiv = ({height, id, currentId, setMoveDiv, moveDiv, times}) => {
const [time, setTime] = useState('')
useEffect(() => {
setTime(times)
},[times])
const timeToHeight = (time) => {
let TotalPrevHeigh = 0;
let i = 0
while ( id > moveDiv[i].id ) {
TotalPrevHeigh += moveDiv[i].height
i++
}
time = NoTemplateTime(time)
let oldHeight = moveDiv[id-1].height
let newHeight = (time-3)/(23-3)*400 - TotalPrevHeigh
let differenceHeight = newHeight - oldHeight
setMoveDiv(prev => prev.map(pre => pre.id == id ? {...pre, height: newHeight} : pre))
setMoveDiv(prev => (prev.map(pre => pre.id == id + 1 ? {...pre, height: moveDiv[id].height - differenceHeight} : pre)))
}
return (
<div>
<div style={{height: height, width: 100, backgroundColor: "red"}}></div>
<div style={{display: "inline-block", width: 100, backgroundColor: "red"}} onMouseDown={()=>{currentId.current = id}} >
sleep mij
</div>
<input
type="time"
value={currentId.current==id ? times : time}
onChange= {(e) => { setTime(e.target.value) }}
onBlur={ (e) => { timeToHeight(e.target.value) }}
/>
</div>
)
}
export default MoveDiv

React Konva - Performance of large number of nodes

I am trying to draw large number of nodes in React Konva based on this performance demo.
My code:
const ZoomTest = (props) => {
let width = window.innerWidth;
let height = window.innerHeight;
const [rects, setRects] = useState([])
const [node, setNode] = useState(null)
function makeRects () {
for (let x=0; x<10000; x++) {
var color = colors[colorIndex++];
if (colorIndex >= colors.length) {
colorIndex = 0;
}
let randX = Math.random() * width;
let randY = Math.random() * height;
rects.push(<Circle
id={x}
x={randX}
y={randY}
width={20}
height={20}
fill={color}
stroke={'blue'}
strokeWidth={1}
shadowBlur={0}
/>)
}
setRects(rects)
}
function getRects() {
if (rects.length === 0)
makeRects()
return rects
}
function tooltip() {
if (node === null)
return null
return <Label x={node.x} y={node.y} opacity={0.75}>
<Tag fill={'black'} pointerDirection={'down'} pointerWidth={10} pointerHeight={10} lineJoin={'round'} shadowColor={'black'}
shadowBlur={10} shadowOffsetX={10} shadowOffsetY={10} shadowOpacity={0.2}/>
<Text text={node.text} fill={'white'} fontSize={18} padding={5} />
</Label>
}
function onMouseOver(evt) {
var node = evt.target;
if (node) {
// update tooltip
var mousePos = node.getStage().getPointerPosition();
setNode({ x: mousePos.x, y: mousePos.y, text: node.id() })
console.log('node id = ', node.id())
}
}
return (
<Stage
width={window.innerWidth}
height={window.innerHeight}
draggable='false'
onMouseOver={onMouseOver}
onMouseMove={onMouseOver}
onDragMove={onMouseOver}
>
<Layer>
{getRects()}
</Layer>
<Layer>
{tooltip()}
</Layer>
</Stage>
)
}
The issue is that tooltip is very slow as compared to the demo. I think this is due to re-renders of the component on every mouse event and this is causing the lag.
Any idea how to make the react-konva performance similar to konvajs?
There is nothing special about react-konva. It is just React performance. In your render function, you have a large list of elements. Every time your state changes (on every mouseover) the react have to compare old structure with the new one. As you have many elements, it takes time to React to check it.
I think there are many ways to solve the issue. As one solution you can just move large list into another component and use React.memo to tell React that you don't need to recheck the whole list every time.
import React from "react";
import { render } from "react-dom";
import { Stage, Layer, Circle, Label, Tag, Text } from "react-konva";
var colors = ["red", "orange", "cyan", "green", "blue", "purple"];
const Rects = React.memo(({ rects }) => {
return (
<React.Fragment>
{rects.map(rect => (
<Circle
key={rect.id}
id={rect.id}
x={rect.x}
y={rect.y}
width={20}
height={20}
fill={rect.color}
stroke={"blue"}
strokeWidth={1}
shadowBlur={0}
/>
))}
</React.Fragment>
);
});
function makeRects() {
let width = window.innerWidth;
let height = window.innerHeight;
const rects = [];
let colorIndex = 0;
for (let x = 0; x < 10000; x++) {
var color = colors[colorIndex++];
if (colorIndex >= colors.length) {
colorIndex = 0;
}
let randX = Math.random() * width;
let randY = Math.random() * height;
rects.push({ id: x, x: randX, y: randY, color });
}
return rects;
}
const INITIAL = makeRects();
const App = props => {
const [rects, setRects] = React.useState(INITIAL);
const [node, setNode] = React.useState(null);
function tooltip() {
if (node === null) return null;
return (
<Label x={node.x} y={node.y} opacity={0.75}>
<Tag
fill={"black"}
pointerDirection={"down"}
pointerWidth={10}
pointerHeight={10}
lineJoin={"round"}
shadowColor={"black"}
shadowBlur={10}
shadowOffsetX={10}
shadowOffsetY={10}
shadowOpacity={0.2}
/>
<Text text={node.text} fill={"white"} fontSize={18} padding={5} />
</Label>
);
}
function onMouseOver(evt) {
var node = evt.target;
if (node) {
// update tooltip
var mousePos = node.getStage().getPointerPosition();
setNode({ x: mousePos.x, y: mousePos.y, text: node.id() });
console.log("node id = ", node.id());
}
}
return (
<Stage
width={window.innerWidth}
height={window.innerHeight}
draggable="false"
onMouseOver={onMouseOver}
onMouseMove={onMouseOver}
onDragMove={onMouseOver}
>
<Layer>
<Rects rects={rects} />
</Layer>
<Layer>{tooltip()}</Layer>
</Stage>
);
};
render(<App />, document.getElementById("root"));
https://codesandbox.io/s/react-konva-performance-on-many-elements-y680w?file=/src/index.js

React: How do you distribute and array of elements evenly across n rows?

Based on screensize, I am looking to distribute an array of x items across n rows dynamically in React. I want each row as an individual div that I can manipulate separately, as I want to be able to scroll X each row individually. Ergo - no flexbox here guys ;)
Using useEffect I will create a state variable that determines the amount of rows to be displayed, and from that, I need a way to split an array of perhaps 50 images, evenly across this row count.
import React, { useEffect, useState } from 'react';
export default function Home() {
const [rows, setRows] = useState(2)
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
// 50 pixels standard grid element width
const gridWidth = 50;
// Temporary tiles array
const tiles: [{ color: string, width: number }?] = [];
for (let index = 0; index < 50; index++) {
tiles.push({
color: getRandomColor(),
width: gridWidth * (Math.floor(Math.random() * 6) + 1)
})
}
console.log(tiles);
const handleScroll = (e: React.WheelEvent<HTMLDivElement>) => {
e.preventDefault();
console.log(e.deltaX)
};
// Splice array into X rows depending on screen height
const renderTiles = (i: number) => {
let j = 1 + i;
for (let index = 0; index < tiles.length; index += j) {
return <div className="tile" style={{ width: tiles[index]?.width, backgroundColor: tiles[index]?.color }}></div>
}
}
const renderRows = () => {
for (let index = 1; index < rows; index++) {
return <div className="row" onWheel={handleScroll}>{renderTiles(index)}</div>
}
}
return (
<div id="wrapper">
{renderRows()}
</div>
)
}
I think I found the issue.. I was for looping when not possible for JSX returns. This script is the one working..
export default function Home() {
const [rows, setRows] = useState(3)
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
// 50 pixels standard grid element width
const gridWidth = 50;
// Temporary tiles array
const tiles: [{ color: string, width: number }?] = [];
for (let index = 0; index < 50; index++) {
tiles.push({
color: getRandomColor(),
width: gridWidth * (Math.floor(Math.random() * 6) + 1)
})
}
const handleScroll = (e: React.WheelEvent<HTMLDivElement>) => {
e.preventDefault();
// console.log(e.deltaX)
};
// Splice array into X rows depending on screen height
const renderTiles = (i: number) => {
const rowTiles = [];
let j = 1 + i;
for (let index = j; index < tiles.length; index += rows) {
rowTiles.push(<div key={index + j + "tile"} className="tile" style={{ width: tiles[index]?.width, backgroundColor: tiles[index]?.color }}></div>)
}
return rowTiles;
}
const renderRows = () => {
const gridRows = []
for (let index = 0; index < rows; index++) {
gridRows.push(<div key={index + "row"} className="row" onWheel={handleScroll}>{renderTiles(index)}</div>);
}
return gridRows
}
return (
<div id="wrapper">
{renderRows().map(r => { console.log('hi'); return r; })}
</div>
)
}

Bubble Sort Visualizer problem with resizing and pressing button

I'm making Bubble Sort visualizer in React.
I've already done it and it's working, but what i want is that it is responsive so i am making that number of bars would shrink, i am doing it by dividing width and 14, because width of one bar is 8px and margin-right is 6px, but when i click button it wont work until i resize it, when i resize it then it will work
Here is my component SortingVisualization.js
import React, { Component } from "react";
import bubbleSort from "../algorithms/bubbleSort";
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
class SortingVisualizer extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
numberOfBars: 100,
widthOfBars: 8,
width: 0,
height: 0,
};
this.bubbleSortImp = this.bubbleSortImp.bind(this);
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
this.updateNumberOfBars = this.updateNumberOfBars.bind(this);
this.randomArray = this.randomArray.bind(this);
}
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener("resize", this.updateWindowDimensions);
this.updateNumberOfBars();
window.addEventListener("resize", this.updateNumberOfBars);
this.randomArray();
window.addEventListener("resize", this.randomArray);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWindowDimensions);
window.removeEventListener("resize", this.updateNumberOfBars);
window.removeEventListener("resize", this.randomArray);
}
updateWindowDimensions() {
this.setState({ width: window.innerWidth, height: window.innerHeight });
}
updateNumberOfBars() {
let num = Math.floor(this.state.width / 15);
this.setState({ numberOfBars: num });
}
randomArray() {
let arr = [];
for (let i = 0; i < this.state.numberOfBars; i++) {
arr.push(this.randomNumber());
}
this.setState({ list: [...arr] });
}
randomNumber() {
let randomIndex = Math.floor(Math.random() * 100) + 1;
return randomIndex;
}
async bubbleSortImp(e) {
e.preventDefault();
let arr = this.state.list;
let len = this.state.list.length;
for (let i = 0; i < this.state.numberOfBars; i++) {
await sleep(50);
bubbleSort(arr, 0, len - 1);
this.setState({ list: [...arr] });
}
}
render() {
console.log(this.state.numberOfBars);
console.log(this.state.width);
return (
<>
<div className="sortingVisualizer">
{this.state.list.map((number, index) => (
<div
key={index}
style={{
height: `${number}` * 5,
width: this.state.widthOfBars,
}}
className="visualize"
></div>
))}
</div>
<div className="buttons">
<button className="btn" onClick={this.bubbleSortImp}>
Bubble Sort
</button>
</div>
</>
);
}
}
export default SortingVisualizer;
Here is my bubbleSort.js
let i = 0;
let j = 0;
const bubbleSort = (arr) => {
if (i < arr.length) {
for (let j = 0; j < arr.length - i - 1; j++) {
let a = arr[j];
let b = arr[j + 1];
if (a > b) {
swap(arr, j, j + 1);
}
}
}
i++;
};
const swap = (arr, a, b) => {
let temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
};
export default bubbleSort;
Here is video what is happening
https://streamable.com/0kk5yt
Here is GitHub Repo
https://github.com/sk0le/sorting-visualization
I found few issues in your implementation and modified the code accordingly. Please refer the below component code and the helper bubbleSort code as well. Hope this helps in resolving your issue.
Initially the sorting was not working because in componentDidMount you were setting the numberOfBars using the computed width but by that time the width didn't get updated in the state, hence the default value is 0. This is making numberOfBars to 0.
And in the utility method, sorting is not happening once the i >= array.lenth as the value is not reset to 0. Found these issues and updated the code accordingly.
Below is the updated code for SortingVisualizer,
//SortingVisualizer.js
import React, { Component } from "react";
import bubbleSort from "../algorithms/bubbleSort";
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
class SortingVisualizer extends Component {
constructor(props) {
super(props);
this.state = {
list: [],
numberOfBars: 100,
widthOfBars: 8,
width: window.innerWidth,
height: window.innerHeight
};
this.bubbleSortImp = this.bubbleSortImp.bind(this);
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
this.randomArray = this.randomArray.bind(this);
}
getDerivedStateFromProps = (nextProps, prevState) => {
if (
prevState.width !== window.innerWidth ||
prevState.height !== window.innerHeight
) {
return {
width: window.innerWidth,
height: window.innerHeight
};
}
};
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener("resize", this.updateWindowDimensions);
this.randomArray();
window.addEventListener("resize", this.randomArray);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWindowDimensions);
window.removeEventListener("resize", this.randomArray);
}
updateWindowDimensions() {
const width = window.innerWidth;
let num = Math.floor(width / 15);
this.setState(() => ({
width,
height: window.innerHeight,
numberOfBars: num
}));
}
randomArray() {
let arr = [];
for (let i = 0; i < this.state.numberOfBars; i++) {
arr.push(this.randomNumber());
}
this.setState(() => ({ list: [...arr] }));
}
randomNumber() {
let randomIndex = Math.floor(Math.random() * 100) + 1;
return randomIndex;
}
async bubbleSortImp(e) {
e.preventDefault();
let arr = this.state.list;
let len = this.state.list.length;
for (let i = 0; i < this.state.numberOfBars; i++) {
await sleep(50);
bubbleSort(arr, 0, len - 1);
this.setState(() => ({ list: [...arr] }));
}
}
render() {
console.log(this.state.numberOfBars);
console.log(this.state.width);
return (
<>
<div className="sortingVisualizer">
{this.state.list.map((number, index) => (
<div
key={index}
style={{
height: `${number}` * 5,
width: this.state.widthOfBars
}}
className="visualize"
></div>
))}
</div>
<div className="buttons">
<button className="btn" onClick={this.bubbleSortImp}>
Bubble Sort
</button>
</div>
</>
);
}
}
export default SortingVisualizer;
Below is the updated code for the utility bubbleSort
let i = 0;
let j = 0;
const bubbleSort = arr => {
if (i < arr.length) {
for (let j = 0; j < arr.length - i - 1; j++) {
let a = arr[j];
let b = arr[j + 1];
if (a > b) {
swap(arr, j, j + 1);
}
}
} else {
i = 0;
return;
}
i++;
};
const swap = (arr, a, b) => {
let temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
};
export default bubbleSort;

Resources