Skip to content

Commit 769cfcc

Browse files
Co-authored-by: dryczek01 <[email protected]>
Co-authored-by: pinardo88 <[email protected]>
2 parents 67da2d5 + 160b062 commit 769cfcc

22 files changed

+818
-247
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
You can view your application's file structure and click on a snapshot to view
4242
your app's state. State can be visualized in a Component Graph, JSON Tree, or
4343
Performance Graph. Snapshot history can be visualized in the History tab.
44-
The Web Metrics tab provides some useful metrics for site performance. The accessibility tab
44+
The Web Metrics tab provides some useful metrics for site performance. The accessibility tab
4545
visualizes an app's accessibility tree per state change.
4646
Snapshots can be compared with the previous snapshot, which can be viewed in Diff mode.
4747
<br>
@@ -89,7 +89,7 @@ Download the recorded snapshots as a JSON file and upload them to access state t
8989
</p>
9090
<br>
9191

92-
### 🔹 Reconnect and Status
92+
### 🔹 and Status
9393

9494
If Reactime loses its connection to the tab you're monitoring, simply click the "reconnect" button to resume your work. You'll notice a circle located to the right of the button, which will appear as either red (indicating disconnection) or green (signifying a successful reconnection).
9595
<br>

demo-app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
},
1010
"devDependencies": {
1111
"@babel/core": "^7.16.7",
12+
"@babel/plugin-transform-runtime": "^7.25.9",
1213
"@babel/preset-env": "^7.16.7",
1314
"@babel/preset-react": "^7.16.7",
1415
"@types/express": "^4.17.13",
@@ -17,6 +18,7 @@
1718
"@types/react-dom": "^17.0.19",
1819
"babel-loader": "^8.2.3",
1920
"copy-webpack-plugin": "^10.2.0",
21+
"core-js": "^3.39.0",
2022
"css-loader": "^6.5.1",
2123
"html-webpack-plugin": "^5.5.0",
2224
"node": "^16.0.0",
Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,82 @@
1-
import React from 'react';
2-
import Increment from './Increment';
1+
import React, { Component, useState } from 'react';
32

4-
function Buttons(): JSX.Element {
5-
const buttons = [];
6-
for (let i = 0; i < 4; i++) {
7-
buttons.push(<Increment key={i} />);
3+
type ButtonProps = {
4+
id: string;
5+
label: string;
6+
color?: string;
7+
initialCount?: number;
8+
};
9+
10+
type IncrementClassState = {
11+
count: number;
12+
};
13+
14+
class IncrementClass extends Component<ButtonProps, IncrementClassState> {
15+
state = {
16+
count: this.props.initialCount || 0,
17+
};
18+
19+
handleClick = (): void => {
20+
this.setState((prevState: IncrementClassState) => ({
21+
count: prevState.count + 1,
22+
}));
23+
};
24+
25+
render(): JSX.Element {
26+
return (
27+
<div>
28+
<button
29+
id={this.props.id}
30+
className='increment'
31+
onClick={this.handleClick}
32+
style={{ backgroundColor: this.props.color }}
33+
>
34+
{this.props.label} {this.state.count} times.
35+
</button>
36+
</div>
37+
);
838
}
39+
}
40+
41+
const IncrementFunction = (props: ButtonProps): JSX.Element => {
42+
const [count, setCount] = useState(props.initialCount || 0);
43+
44+
const handleClick = (): void => {
45+
setCount((prev) => prev + 1);
46+
};
947

1048
return (
11-
<div className='buttons'>
12-
<h1>Stateful Buttons</h1>
13-
<h4>
14-
These buttons are functional components that each manage their own state with the useState
15-
hook.
16-
</h4>
17-
{buttons}
49+
<div>
50+
<button
51+
id={props.id}
52+
className='increment'
53+
onClick={handleClick}
54+
style={{ backgroundColor: props.color }}
55+
>
56+
{props.label} {count} times.
57+
</button>
1858
</div>
1959
);
60+
};
61+
62+
class Buttons extends Component {
63+
render(): JSX.Element {
64+
return (
65+
<div className='buttons'>
66+
<h1>Mixed State Counter</h1>
67+
<h4>First two buttons use class components, last two use function components.</h4>
68+
<IncrementClass id='class1' label='Class Button 1:' color='#f00008' initialCount={5} />
69+
<IncrementClass id='class2' label='Class Button 2:' color='#62d6fb' />
70+
<IncrementFunction
71+
id='func1'
72+
label='Function Button 1:'
73+
color='#6288fb'
74+
initialCount={10}
75+
/>
76+
<IncrementFunction id='func2' label='Function Button 2:' color='#ff6569' />
77+
</div>
78+
);
79+
}
2080
}
2181

2282
export default Buttons;
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import React, { useState, useReducer } from 'react';
2+
3+
type CounterProps = {
4+
initialCount?: number;
5+
step?: number;
6+
title?: string;
7+
theme?: {
8+
backgroundColor?: string;
9+
textColor?: string;
10+
};
11+
};
12+
13+
type CounterState = {
14+
count: number;
15+
history: number[];
16+
lastAction: string;
17+
};
18+
19+
type CounterAction =
20+
| { type: 'INCREMENT' }
21+
| { type: 'DECREMENT' }
22+
| { type: 'DOUBLE' }
23+
| { type: 'RESET' }
24+
| { type: 'ADD'; payload: number };
25+
26+
function counterReducer(state: CounterState, action: CounterAction, step: number): CounterState {
27+
switch (action.type) {
28+
case 'INCREMENT':
29+
return {
30+
...state,
31+
count: state.count + step,
32+
history: [...state.history, state.count + step],
33+
lastAction: 'INCREMENT',
34+
};
35+
case 'DECREMENT':
36+
return {
37+
...state,
38+
count: state.count - step,
39+
history: [...state.history, state.count - step],
40+
lastAction: 'DECREMENT',
41+
};
42+
case 'DOUBLE':
43+
return {
44+
...state,
45+
count: state.count * 2,
46+
history: [...state.history, state.count * 2],
47+
lastAction: 'DOUBLE',
48+
};
49+
case 'RESET':
50+
return {
51+
count: 0,
52+
history: [],
53+
lastAction: 'RESET',
54+
};
55+
case 'ADD':
56+
return {
57+
...state,
58+
count: state.count + action.payload,
59+
history: [...state.history, state.count + action.payload],
60+
lastAction: `ADD ${action.payload}`,
61+
};
62+
default:
63+
return state;
64+
}
65+
}
66+
67+
function FunctionalReducerCounter({
68+
initialCount = 0,
69+
step = 1,
70+
title = 'Function-based Reducer Counter',
71+
theme = {
72+
backgroundColor: '#ffffff',
73+
textColor: '#330002',
74+
},
75+
}: CounterProps): JSX.Element {
76+
const [clickCount, setClickCount] = useState(0);
77+
const [lastClickTime, setLastClickTime] = useState<Date | null>(null);
78+
const [averageTimeBetweenClicks, setAverageTimeBetweenClicks] = useState<number>(0);
79+
const [state, dispatch] = useReducer(
80+
(state: CounterState, action: CounterAction) => counterReducer(state, action, step),
81+
{
82+
count: initialCount,
83+
history: [],
84+
lastAction: 'none',
85+
},
86+
);
87+
88+
return (
89+
<div
90+
className='reducer-counter'
91+
style={{
92+
backgroundColor: theme.backgroundColor,
93+
color: theme.textColor,
94+
}}
95+
>
96+
<h2>{title}</h2>
97+
<div className='counter-value'>
98+
<h3>Current Count: {state.count}</h3>
99+
</div>
100+
101+
<div className='counter-buttons'>
102+
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment (+{step})</button>
103+
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement (-{step})</button>
104+
<button onClick={() => dispatch({ type: 'DOUBLE' })}>Double Value</button>
105+
<button onClick={() => dispatch({ type: 'ADD', payload: 5 })}>Add 5</button>
106+
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
107+
</div>
108+
109+
<div className='counter-info'>
110+
<h4>Last Action: {state.lastAction}</h4>
111+
<h4>History:</h4>
112+
<div className='history-list'>
113+
{state.history.map((value, index) => (
114+
<span key={index}>
115+
{value}
116+
{index < state.history.length - 1 ? ' → ' : ''}
117+
</span>
118+
))}
119+
</div>
120+
</div>
121+
</div>
122+
);
123+
}
124+
export default FunctionalReducerCounter;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React, { useState } from 'react';
2+
3+
type CounterProps = {
4+
initialCount?: number;
5+
step?: number;
6+
title?: string;
7+
theme?: {
8+
backgroundColor?: string;
9+
textColor?: string;
10+
};
11+
};
12+
13+
function FunctionalStateCounter({
14+
initialCount = 0,
15+
step = 1,
16+
title = 'Function-based State Counter',
17+
theme = {
18+
backgroundColor: '#ffffff',
19+
textColor: '#330002',
20+
},
21+
}: CounterProps): JSX.Element {
22+
const [count, setCount] = useState(initialCount);
23+
const [history, setHistory] = useState<number[]>([]);
24+
const [lastAction, setLastAction] = useState('none');
25+
26+
const handleAction = (type: string, payload?: number) => {
27+
let newCount = count;
28+
switch (type) {
29+
case 'INCREMENT':
30+
newCount = count + step;
31+
setCount(newCount);
32+
setHistory([...history, newCount]);
33+
setLastAction('INCREMENT');
34+
break;
35+
case 'DECREMENT':
36+
newCount = count - step;
37+
setCount(newCount);
38+
setHistory([...history, newCount]);
39+
setLastAction('DECREMENT');
40+
break;
41+
case 'DOUBLE':
42+
newCount = count * 2;
43+
setCount(newCount);
44+
setHistory([...history, newCount]);
45+
setLastAction('DOUBLE');
46+
break;
47+
case 'ADD':
48+
newCount = count + (payload || 0);
49+
setCount(newCount);
50+
setHistory([...history, newCount]);
51+
setLastAction(`ADD ${payload}`);
52+
break;
53+
case 'RESET':
54+
setCount(0);
55+
setHistory([]);
56+
setLastAction('RESET');
57+
break;
58+
}
59+
};
60+
61+
return (
62+
<div
63+
className='reducer-counter'
64+
style={{
65+
backgroundColor: theme.backgroundColor,
66+
color: theme.textColor,
67+
}}
68+
>
69+
<h2>{title}</h2>
70+
<div className='counter-value'>
71+
<h3>Current Count: {count}</h3>
72+
</div>
73+
74+
<div className='counter-buttons'>
75+
<button onClick={() => handleAction('INCREMENT')}>Increment (+{step})</button>
76+
<button onClick={() => handleAction('DECREMENT')}>Decrement (-{step})</button>
77+
<button onClick={() => handleAction('DOUBLE')}>Double Value</button>
78+
<button onClick={() => handleAction('ADD', 5)}>Add 5</button>
79+
<button onClick={() => handleAction('RESET')}>Reset</button>
80+
</div>
81+
82+
<div className='counter-info'>
83+
<h4>Last Action: {lastAction}</h4>
84+
<h4>History:</h4>
85+
<div className='history-list'>
86+
{history.map((value, index) => (
87+
<span key={index}>
88+
{value}
89+
{index < history.length - 1 ? ' → ' : ''}
90+
</span>
91+
))}
92+
</div>
93+
</div>
94+
</div>
95+
);
96+
}
97+
98+
export default FunctionalStateCounter;

demo-app/src/client/Components/Increment.tsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

demo-app/src/client/Components/Nav.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ function Nav(): JSX.Element {
1111
Tic-Tac-Toe
1212
</Link>
1313
<Link className='link' to='/buttons'>
14-
Counter
14+
State Counter
15+
</Link>
16+
<Link className='link' to='/reducer'>
17+
Reducer Counter
1518
</Link>
1619
</div>
1720
);

0 commit comments

Comments
 (0)