Skip to content

Commit 9b7d86a

Browse files
committed
Refactor: Codebase Cleanup #2, use refs to trigger visualizer methods
1 parent 9a2f41f commit 9b7d86a

File tree

9 files changed

+96
-103
lines changed

9 files changed

+96
-103
lines changed

src/App.tsx

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { SelectionsortVisualizer } from './components/visualizers/SelectionsortVisualizer.tsx';
22
import { BubblesortVisualizer } from './components/visualizers/BubblesortVisualizer.tsx';
33
import { MergeSortVisualizer } from './components/visualizers/MergesortVisualizer.tsx';
4-
import { useState } from 'react';
4+
import { useEffect, useRef, useState } from 'react';
55
import { Container, Row } from 'react-bootstrap';
66
import { generateRandomArray } from './utils';
7-
import { SettingsPanel } from './components/settings/SettingsPanel.tsx';
7+
import { SettingsPanel } from './components/panels/SettingsPanel.tsx';
88
import { Navigation } from './components/navigation/Navigation.tsx';
9+
import { ControlPanel } from './components/panels/ControlPanel.tsx';
910

1011
// todo: refactor the components, upcycle shared states
1112
export const App = () => {
@@ -15,6 +16,21 @@ export const App = () => {
1516
const [isSorting, setIsSorting] = useState<boolean>(false);
1617
const [array, setArray] = useState<number[]>(generateRandomArray(arraySize));
1718

19+
// sort method refs
20+
const bubbleSortRef = useRef<(array: number[]) => void>(() => {}); // initialize with an empty function (ts error)
21+
const selectionSortRef = useRef<(array: number[]) => void>(() => {});
22+
const mergeSortRef = useRef<(array: number[]) => void>(() => {});
23+
24+
const resetComponent = () => {
25+
const newArray = generateRandomArray(arraySize);
26+
setArray(newArray);
27+
};
28+
29+
useEffect(() => {
30+
const array = generateRandomArray(arraySize);
31+
setArray(array);
32+
}, [arraySize]);
33+
1834
const renderVisualizer = () => {
1935
switch (sortType) {
2036
case 'bubble':
@@ -26,6 +42,7 @@ export const App = () => {
2642
sortDelay={sortDelay}
2743
isSorting={isSorting}
2844
setIsSorting={setIsSorting}
45+
sortRef={bubbleSortRef}
2946
/>
3047
);
3148
case 'selection':
@@ -37,6 +54,7 @@ export const App = () => {
3754
sortDelay={sortDelay}
3855
isSorting={isSorting}
3956
setIsSorting={setIsSorting}
57+
sortRef={selectionSortRef}
4058
/>
4159
);
4260
case 'merge':
@@ -48,6 +66,7 @@ export const App = () => {
4866
sortDelay={sortDelay}
4967
isSorting={isSorting}
5068
setIsSorting={setIsSorting}
69+
sortRef={mergeSortRef}
5170
/>
5271
);
5372
default:
@@ -59,14 +78,19 @@ export const App = () => {
5978
sortDelay={sortDelay}
6079
isSorting={isSorting}
6180
setIsSorting={setIsSorting}
81+
sortRef={bubbleSortRef}
6282
/>
6383
);
6484
}
6585
};
6686

6787
return (
6888
<>
69-
<Navigation sortType={sortType} setSortType={setSortType} />
89+
<Navigation
90+
sortType={sortType}
91+
setSortType={setSortType}
92+
isSorting={isSorting}
93+
/>
7094
<Container>
7195
<Row className="mt-4">
7296
<SettingsPanel
@@ -78,6 +102,26 @@ export const App = () => {
78102
/>
79103
</Row>
80104
{renderVisualizer()}
105+
<ControlPanel
106+
isSorting={isSorting}
107+
onGenerate={resetComponent}
108+
onSort={() => {
109+
switch (sortType) {
110+
case 'bubble':
111+
bubbleSortRef.current && bubbleSortRef.current(array);
112+
break;
113+
case 'selection':
114+
selectionSortRef.current && selectionSortRef.current(array);
115+
break;
116+
case 'merge':
117+
mergeSortRef.current && mergeSortRef.current(array);
118+
break;
119+
default:
120+
bubbleSortRef.current && bubbleSortRef.current(array);
121+
break;
122+
}
123+
}}
124+
/>
81125
</Container>
82126
</>
83127
);

src/components/navigation/Navigation.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import React from 'react';
66
export const Navigation: React.FC<NavigationProps> = ({
77
sortType,
88
setSortType,
9+
isSorting,
910
}) => {
1011
return (
1112
<Navbar collapseOnSelect expand="lg" className="bg-body-tertiary">
@@ -24,6 +25,7 @@ export const Navigation: React.FC<NavigationProps> = ({
2425
as="select"
2526
value={sortType}
2627
onChange={(e) => setSortType(e.target.value)}
28+
disabled={isSorting}
2729
>
2830
<option value="bubble">Bubblesort</option>
2931
<option value="selection">Selectionsort</option>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from 'react';
2+
import { Button, Col, Row } from 'react-bootstrap';
3+
4+
interface ControlPanelProps {
5+
isSorting: boolean;
6+
onGenerate: () => void;
7+
onSort: () => void;
8+
}
9+
10+
export const ControlPanel: React.FC<ControlPanelProps> = ({
11+
isSorting,
12+
onGenerate,
13+
onSort,
14+
}) => {
15+
return (
16+
<Row className="justify-content-center mt-3">
17+
<Col className="d-flex justify-content-center">
18+
<Button className="mt-5 mx-3" onClick={onGenerate} disabled={isSorting}>
19+
Generate
20+
</Button>
21+
</Col>
22+
<Col className="d-flex justify-content-center">
23+
<Button className="mt-5" onClick={onSort} disabled={isSorting}>
24+
Sort
25+
</Button>
26+
</Col>
27+
</Row>
28+
);
29+
};

src/components/visualizers/BubblesortVisualizer.tsx

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import React, { useEffect, useRef, useState } from 'react';
22
import { useGSAP } from '@gsap/react';
33
import gsap from 'gsap';
4-
import { Button, Col, Container, Row } from 'react-bootstrap';
5-
import { delay, generateRandomArray } from '../../utils';
4+
import { Col, Container, Row } from 'react-bootstrap';
5+
import { delay } from '../../utils';
66
import { VisualizerProps } from '../../interfaces';
77

88
export const BubblesortVisualizer: React.FC<VisualizerProps> = ({
9-
arraySize,
109
array,
1110
setArray,
1211
sortDelay,
13-
isSorting,
1412
setIsSorting,
13+
sortRef,
1514
}) => {
1615
const [currentJ, setCurrentJ] = useState<number | null>(null);
1716

@@ -21,15 +20,8 @@ export const BubblesortVisualizer: React.FC<VisualizerProps> = ({
2120
const { contextSafe } = useGSAP({ scope: container });
2221

2322
useEffect(() => {
24-
const array = generateRandomArray(arraySize);
25-
setArray(array);
26-
}, [arraySize]);
27-
28-
const resetComponent = () => {
29-
const array = generateRandomArray(arraySize);
30-
setArray(array);
31-
setCurrentJ(null);
32-
};
23+
sortRef.current = (array: number[]) => bubbleSort(array);
24+
}, [sortRef]);
3325

3426
const bubbleSort = async (array: number[]) => {
3527
setIsSorting(true);
@@ -130,26 +122,6 @@ export const BubblesortVisualizer: React.FC<VisualizerProps> = ({
130122
</Col>
131123
))}
132124
</Row>
133-
<Row className="justify-content-center mt-3">
134-
<Col className="d-flex justify-content-center">
135-
<Button
136-
className="mt-5 mx-3"
137-
onClick={() => resetComponent()}
138-
disabled={isSorting}
139-
>
140-
Generate
141-
</Button>
142-
</Col>
143-
<Col className="d-flex justify-content-center">
144-
<Button
145-
className="mt-5"
146-
onClick={() => bubbleSort(array)}
147-
disabled={isSorting}
148-
>
149-
Sort
150-
</Button>
151-
</Col>
152-
</Row>
153125
</Container>
154126
</>
155127
);

src/components/visualizers/MergesortVisualizer.tsx

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,23 @@
11
import React, { useEffect, useRef } from 'react';
22
import { useGSAP } from '@gsap/react';
33
import gsap from 'gsap';
4-
import { Button, Col, Container, Row } from 'react-bootstrap';
5-
import { generateRandomArray } from '../../utils';
4+
import { Col, Container, Row } from 'react-bootstrap';
65
import { VisualizerProps } from '../../interfaces';
76

87
export const MergeSortVisualizer: React.FC<VisualizerProps> = ({
9-
arraySize,
108
array,
119
setArray,
12-
//sortDelay,
13-
isSorting,
1410
setIsSorting,
11+
sortRef,
1512
}) => {
1613
const boxRefs = useRef<(HTMLDivElement | null)[]>([]);
1714
const container = useRef(null);
1815
const { contextSafe } = useGSAP({ scope: container });
1916
const tl = gsap.timeline(); // todo: find better way than using global gsap timeline element
2017

2118
useEffect(() => {
22-
resetComponent();
23-
}, [arraySize]);
24-
25-
const resetComponent = () => {
26-
const array = generateRandomArray(arraySize);
27-
setArray(array);
28-
};
19+
sortRef.current = () => startSort();
20+
}, [sortRef]);
2921

3022
const mergeSort = async (array: number[], left = 0): Promise<number[]> => {
3123
if (array.length <= 1) {
@@ -153,26 +145,6 @@ export const MergeSortVisualizer: React.FC<VisualizerProps> = ({
153145
</Col>
154146
))}
155147
</Row>
156-
<Row className="justify-content-center mt-3">
157-
<Col className="d-flex justify-content-center">
158-
<Button
159-
className="mt-5 mx-3"
160-
onClick={() => resetComponent()}
161-
disabled={isSorting}
162-
>
163-
Generate
164-
</Button>
165-
</Col>
166-
<Col className="d-flex justify-content-center">
167-
<Button
168-
className="mt-5"
169-
onClick={() => startSort()}
170-
disabled={isSorting}
171-
>
172-
Sort
173-
</Button>
174-
</Col>
175-
</Row>
176148
</Container>
177149
</>
178150
);

src/components/visualizers/SelectionsortVisualizer.tsx

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import React, { useEffect, useRef, useState } from 'react';
22
import { useGSAP } from '@gsap/react';
33
import gsap from 'gsap';
4-
import { Button, Col, Container, Row } from 'react-bootstrap';
5-
import { delay, generateRandomArray } from '../../utils';
4+
import { Col, Container, Row } from 'react-bootstrap';
5+
import { delay } from '../../utils';
66
import { VisualizerProps } from '../../interfaces';
77

88
export const SelectionsortVisualizer: React.FC<VisualizerProps> = ({
9-
arraySize,
109
array,
1110
setArray,
1211
sortDelay,
13-
isSorting,
1412
setIsSorting,
13+
sortRef,
1514
}) => {
1615
const [currentI, setCurrentI] = useState<number | null>(null);
1716
const [currentJ, setCurrentJ] = useState<number | null>(null);
@@ -23,17 +22,8 @@ export const SelectionsortVisualizer: React.FC<VisualizerProps> = ({
2322
const { contextSafe } = useGSAP({ scope: container });
2423

2524
useEffect(() => {
26-
const array = generateRandomArray(arraySize);
27-
setArray(array);
28-
}, [arraySize]);
29-
30-
const resetComponent = () => {
31-
const array = generateRandomArray(arraySize);
32-
setArray(array);
33-
setCurrentI(null);
34-
setCurrentJ(null);
35-
setCurrentMin(null);
36-
};
25+
sortRef.current = (array: number[]) => selectionSort(array);
26+
}, [sortRef]);
3727

3828
const selectionSort = async (array: number[]) => {
3929
let min = null;
@@ -157,26 +147,6 @@ export const SelectionsortVisualizer: React.FC<VisualizerProps> = ({
157147
</Col>
158148
))}
159149
</Row>
160-
<Row className="justify-content-center mt-3">
161-
<Col className="d-flex justify-content-center">
162-
<Button
163-
className="mt-5 mx-3"
164-
onClick={() => resetComponent()}
165-
disabled={isSorting}
166-
>
167-
Generate
168-
</Button>
169-
</Col>
170-
<Col className="d-flex justify-content-center">
171-
<Button
172-
className="mt-5"
173-
onClick={() => selectionSort(array)}
174-
disabled={isSorting}
175-
>
176-
Sort
177-
</Button>
178-
</Col>
179-
</Row>
180150
</Container>
181151
</>
182152
);

src/interfaces/navigation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export interface NavigationProps {
22
sortType: string;
33
setSortType: (sortType: string) => void;
4+
isSorting: boolean;
45
}

src/interfaces/visualizers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import { MutableRefObject } from 'react';
2+
13
export interface VisualizerProps {
24
arraySize: number;
35
array: number[];
46
setArray: (array: number[]) => void;
57
sortDelay: number;
68
isSorting: boolean;
79
setIsSorting: (sorting: boolean) => void;
10+
sortRef: MutableRefObject<(array: number[]) => void>;
811
}

0 commit comments

Comments
 (0)