Skip to content

Commit 9f2b5af

Browse files
committed
fixed correct reducer and state differentiation
1 parent 45107cf commit 9f2b5af

File tree

5 files changed

+137
-60
lines changed

5 files changed

+137
-60
lines changed

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

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import React, { Component, useState } from 'react';
22

3-
// Type for IncrementClass state
3+
type ButtonProps = {
4+
id: string;
5+
label: string;
6+
color?: string;
7+
initialCount?: number;
8+
};
9+
410
type IncrementClassState = {
511
count: number;
612
};
713

8-
// Class-based Increment Component
9-
class IncrementClass extends Component<{}, IncrementClassState> {
14+
class IncrementClass extends Component<ButtonProps, IncrementClassState> {
1015
state = {
11-
count: 0,
16+
count: this.props.initialCount || 0,
1217
};
1318

1419
handleClick = (): void => {
@@ -20,42 +25,55 @@ class IncrementClass extends Component<{}, IncrementClassState> {
2025
render(): JSX.Element {
2126
return (
2227
<div>
23-
<button className='increment' onClick={this.handleClick}>
24-
You clicked me {this.state.count} times.
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.
2535
</button>
2636
</div>
2737
);
2838
}
2939
}
3040

31-
// Function-based Increment Component
32-
const IncrementFunction = (): JSX.Element => {
33-
const [count, setCount] = useState(0);
41+
const IncrementFunction = (props: ButtonProps): JSX.Element => {
42+
const [count, setCount] = useState(props.initialCount || 0);
3443

3544
const handleClick = (): void => {
3645
setCount((prev) => prev + 1);
3746
};
3847

3948
return (
4049
<div>
41-
<button className='increment' onClick={handleClick}>
42-
You clicked me {count} times.
50+
<button
51+
id={props.id}
52+
className='increment'
53+
onClick={handleClick}
54+
style={{ backgroundColor: props.color }}
55+
>
56+
{props.label} {count} times.
4357
</button>
4458
</div>
4559
);
4660
};
4761

48-
// Main Buttons Component
4962
class Buttons extends Component {
5063
render(): JSX.Element {
5164
return (
5265
<div className='buttons'>
5366
<h1>Mixed State Counter</h1>
5467
<h4>First two buttons use class components, last two use function components.</h4>
55-
<IncrementClass />
56-
<IncrementClass />
57-
<IncrementFunction />
58-
<IncrementFunction />
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' />
5977
</div>
6078
);
6179
}

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

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import React, { useReducer } from 'react';
22

3+
type CounterProps = {
4+
initialCount?: number;
5+
step?: number;
6+
title?: string;
7+
theme?: {
8+
backgroundColor?: string;
9+
textColor?: string;
10+
};
11+
};
12+
313
type CounterState = {
414
count: number;
515
history: number[];
@@ -13,26 +23,20 @@ type CounterAction =
1323
| { type: 'RESET' }
1424
| { type: 'ADD'; payload: number };
1525

16-
const initialState: CounterState = {
17-
count: 0,
18-
history: [],
19-
lastAction: 'none',
20-
};
21-
22-
function counterReducer(state: CounterState, action: CounterAction): CounterState {
26+
function counterReducer(state: CounterState, action: CounterAction, step: number): CounterState {
2327
switch (action.type) {
2428
case 'INCREMENT':
2529
return {
2630
...state,
27-
count: state.count + 1,
28-
history: [...state.history, state.count + 1],
31+
count: state.count + step,
32+
history: [...state.history, state.count + step],
2933
lastAction: 'INCREMENT',
3034
};
3135
case 'DECREMENT':
3236
return {
3337
...state,
34-
count: state.count - 1,
35-
history: [...state.history, state.count - 1],
38+
count: state.count - step,
39+
history: [...state.history, state.count - step],
3640
lastAction: 'DECREMENT',
3741
};
3842
case 'DOUBLE':
@@ -44,7 +48,8 @@ function counterReducer(state: CounterState, action: CounterAction): CounterStat
4448
};
4549
case 'RESET':
4650
return {
47-
...initialState,
51+
count: 0,
52+
history: [],
4853
lastAction: 'RESET',
4954
};
5055
case 'ADD':
@@ -59,19 +64,40 @@ function counterReducer(state: CounterState, action: CounterAction): CounterStat
5964
}
6065
}
6166

62-
function FunctionalReducerCounter(): JSX.Element {
63-
const [state, dispatch] = useReducer(counterReducer, initialState);
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 [state, dispatch] = useReducer(
77+
(state: CounterState, action: CounterAction) => counterReducer(state, action, step),
78+
{
79+
count: initialCount,
80+
history: [],
81+
lastAction: 'none',
82+
},
83+
);
6484

6585
return (
66-
<div className='reducer-counter'>
67-
<h2>Function-based Reducer Counter</h2>
86+
<div
87+
className='reducer-counter'
88+
style={{
89+
backgroundColor: theme.backgroundColor,
90+
color: theme.textColor,
91+
}}
92+
>
93+
<h2>{title}</h2>
6894
<div className='counter-value'>
6995
<h3>Current Count: {state.count}</h3>
7096
</div>
7197

7298
<div className='counter-buttons'>
73-
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment (+1)</button>
74-
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement (-1)</button>
99+
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment (+{step})</button>
100+
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement (-{step})</button>
75101
<button onClick={() => dispatch({ type: 'DOUBLE' })}>Double Value</button>
76102
<button onClick={() => dispatch({ type: 'ADD', payload: 5 })}>Add 5</button>
77103
<button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
@@ -92,5 +118,4 @@ function FunctionalReducerCounter(): JSX.Element {
92118
</div>
93119
);
94120
}
95-
96121
export default FunctionalReducerCounter;

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

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import React, { Component } from 'react';
22

3+
type CounterProps = {
4+
initialCount?: number;
5+
step?: number;
6+
title?: string;
7+
theme?: {
8+
backgroundColor?: string;
9+
textColor?: string;
10+
};
11+
};
12+
313
type CounterState = {
414
count: number;
515
history: number[];
@@ -13,30 +23,39 @@ type CounterAction =
1323
| { type: 'RESET' }
1424
| { type: 'ADD'; payload: number };
1525

16-
// Static reducer function to handle state updates
17-
class ReducerCounter extends Component<{}, CounterState> {
18-
// Initial state definition
19-
static initialState: CounterState = {
20-
count: 0,
21-
history: [],
22-
lastAction: 'none',
26+
class ReducerCounter extends Component<CounterProps, CounterState> {
27+
static defaultProps = {
28+
initialCount: 0,
29+
step: 1,
30+
title: 'Class-based Reducer Counter',
31+
theme: {
32+
backgroundColor: '#ffffff',
33+
textColor: '#330002',
34+
},
2335
};
2436

25-
// Static reducer method to handle state updates
26-
static reducer(state: CounterState, action: CounterAction): CounterState {
37+
static initialState(initialCount: number): CounterState {
38+
return {
39+
count: initialCount,
40+
history: [],
41+
lastAction: 'none',
42+
};
43+
}
44+
45+
static reducer(state: CounterState, action: CounterAction, step: number): CounterState {
2746
switch (action.type) {
2847
case 'INCREMENT':
2948
return {
3049
...state,
31-
count: state.count + 1,
32-
history: [...state.history, state.count + 1],
50+
count: state.count + step,
51+
history: [...state.history, state.count + step],
3352
lastAction: 'INCREMENT',
3453
};
3554
case 'DECREMENT':
3655
return {
3756
...state,
38-
count: state.count - 1,
39-
history: [...state.history, state.count - 1],
57+
count: state.count - step,
58+
history: [...state.history, state.count - step],
4059
lastAction: 'DECREMENT',
4160
};
4261
case 'DOUBLE':
@@ -48,7 +67,7 @@ class ReducerCounter extends Component<{}, CounterState> {
4867
};
4968
case 'RESET':
5069
return {
51-
...ReducerCounter.initialState,
70+
...ReducerCounter.initialState(0),
5271
lastAction: 'RESET',
5372
};
5473
case 'ADD':
@@ -63,30 +82,41 @@ class ReducerCounter extends Component<{}, CounterState> {
6382
}
6483
}
6584

66-
constructor(props: {}) {
85+
constructor(props: CounterProps) {
6786
super(props);
68-
this.state = ReducerCounter.initialState;
69-
70-
// Bind dispatch method
87+
this.state = ReducerCounter.initialState(props.initialCount || 0);
7188
this.dispatch = this.dispatch.bind(this);
7289
}
7390

74-
// Method to handle state updates using the reducer
7591
dispatch(action: CounterAction): void {
76-
this.setState((currentState) => ReducerCounter.reducer(currentState, action));
92+
this.setState((currentState) =>
93+
ReducerCounter.reducer(currentState, action, this.props.step || 1),
94+
);
7795
}
7896

7997
render(): JSX.Element {
98+
const { title, theme } = this.props;
99+
80100
return (
81-
<div className='reducer-counter'>
82-
<h2>Class-based Reducer Counter</h2>
101+
<div
102+
className='reducer-counter'
103+
style={{
104+
backgroundColor: theme?.backgroundColor,
105+
color: theme?.textColor,
106+
}}
107+
>
108+
<h2>{title}</h2>
83109
<div className='counter-value'>
84110
<h3>Current Count: {this.state.count}</h3>
85111
</div>
86112

87113
<div className='counter-buttons'>
88-
<button onClick={() => this.dispatch({ type: 'INCREMENT' })}>Increment (+1)</button>
89-
<button onClick={() => this.dispatch({ type: 'DECREMENT' })}>Decrement (-1)</button>
114+
<button onClick={() => this.dispatch({ type: 'INCREMENT' })}>
115+
Increment (+{this.props.step})
116+
</button>
117+
<button onClick={() => this.dispatch({ type: 'DECREMENT' })}>
118+
Decrement (-{this.props.step})
119+
</button>
90120
<button onClick={() => this.dispatch({ type: 'DOUBLE' })}>Double Value</button>
91121
<button onClick={() => this.dispatch({ type: 'ADD', payload: 5 })}>Add 5</button>
92122
<button onClick={() => this.dispatch({ type: 'RESET' })}>Reset</button>

src/backend/controllers/createTree.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ export default function createTree(currentFiberNode: Fiber): Tree {
147147
// Else filter & format props data to ensure they are JSON stringify-able, before sending to front end
148148
default: {
149149
componentData.props = filterAndFormatData(memoizedProps);
150+
console.log('Default case props for', componentName, ':', componentData.props);
150151
}
151152
}
152153
}
@@ -207,8 +208,11 @@ export default function createTree(currentFiberNode: Fiber): Tree {
207208
if (memoizedState.queue) {
208209
try {
209210
const hooksStates = getHooksStateAndUpdateMethod(memoizedState);
211+
console.log('hook states', hooksStates);
210212
// Get the hooks names by parsing the elementType
213+
console.log('element type', elementType.toString());
211214
const hooksNames = getHooksNames(elementType.toString());
215+
console.log('hook names', hooksNames);
212216

213217
componentData.hooksState = {};
214218
componentData.reducerState = null;

src/backend/controllers/statePropExtractors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function getHooksStateAndUpdateMethod(
7373
if (
7474
memoizedState.queue &&
7575
memoizedState.memoizedState &&
76-
typeof memoizedState.queue.dispatch === 'function'
76+
memoizedState.queue.lastRenderedReducer.name !== 'basicStateReducer' // only present in useState
7777
) {
7878
hooksStates.push({
7979
component: memoizedState.queue,

0 commit comments

Comments
 (0)