Skip to content

Commit 784f646

Browse files
committed
added SET STATE action in reducers
1 parent 5701e79 commit 784f646

File tree

5 files changed

+41
-103
lines changed

5 files changed

+41
-103
lines changed

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

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ type CounterAction =
2121
| { type: 'DECREMENT' }
2222
| { type: 'DOUBLE' }
2323
| { type: 'RESET' }
24-
| { type: 'ADD'; payload: number };
24+
| { type: 'ADD'; payload: number }
25+
| { type: 'SET_STATE'; payload: CounterState };
2526

26-
// New secondary reducer state and action types
2727
type SecondaryCounterState = {
2828
count: number;
2929
multiplier: number;
3030
lastOperation: string;
31+
history: number[];
3132
};
3233

3334
type SecondaryCounterAction =
3435
| { type: 'MULTIPLY' }
3536
| { type: 'DIVIDE' }
3637
| { type: 'SET_MULTIPLIER'; payload: number }
37-
| { type: 'RESET' };
38+
| { type: 'RESET' }
39+
| { type: 'SET_STATE'; payload: SecondaryCounterState };
3840

3941
function counterReducer(state: CounterState, action: CounterAction, step: number): CounterState {
4042
switch (action.type) {
@@ -72,12 +74,16 @@ function counterReducer(state: CounterState, action: CounterAction, step: number
7274
history: [...state.history, state.count + action.payload],
7375
lastAction: `ADD ${action.payload}`,
7476
};
77+
case 'SET_STATE':
78+
return {
79+
...action.payload,
80+
lastAction: 'SET_STATE',
81+
};
7582
default:
7683
return state;
7784
}
7885
}
7986

80-
// New secondary reducer function
8187
function secondaryCounterReducer(
8288
state: SecondaryCounterState,
8389
action: SecondaryCounterAction,
@@ -87,26 +93,35 @@ function secondaryCounterReducer(
8793
return {
8894
...state,
8995
count: state.count * state.multiplier,
96+
history: [...state.history, state.count * state.multiplier],
9097
lastOperation: `Multiplied by ${state.multiplier}`,
9198
};
9299
case 'DIVIDE':
93100
return {
94101
...state,
95102
count: state.count / state.multiplier,
103+
history: [...state.history, state.count / state.multiplier],
96104
lastOperation: `Divided by ${state.multiplier}`,
97105
};
98106
case 'SET_MULTIPLIER':
99107
return {
100108
...state,
101109
multiplier: action.payload,
110+
history: [...state.history],
102111
lastOperation: `Set multiplier to ${action.payload}`,
103112
};
104113
case 'RESET':
105114
return {
106115
count: 0,
107116
multiplier: 2,
117+
history: [],
108118
lastOperation: 'Reset',
109119
};
120+
case 'SET_STATE':
121+
return {
122+
...action.payload,
123+
lastOperation: 'SET_STATE',
124+
};
110125
default:
111126
return state;
112127
}
@@ -125,7 +140,6 @@ function FunctionalReducerCounter({
125140
const [lastClickTime, setLastClickTime] = useState<Date | null>(null);
126141
const [averageTimeBetweenClicks, setAverageTimeBetweenClicks] = useState<number>(0);
127142

128-
// First reducer
129143
const [state, dispatch] = useReducer(
130144
(state: CounterState, action: CounterAction) => counterReducer(state, action, step),
131145
{
@@ -135,10 +149,10 @@ function FunctionalReducerCounter({
135149
},
136150
);
137151

138-
// Second reducer
139152
const [secondaryState, secondaryDispatch] = useReducer(secondaryCounterReducer, {
140153
count: initialCount,
141154
multiplier: 2,
155+
history: [],
142156
lastOperation: 'none',
143157
});
144158

@@ -152,7 +166,6 @@ function FunctionalReducerCounter({
152166
>
153167
<h2>{title}</h2>
154168

155-
{/* Primary Counter Section */}
156169
<div className='counter-value'>
157170
<h3>Primary Counter: {state.count}</h3>
158171
</div>
@@ -166,7 +179,6 @@ function FunctionalReducerCounter({
166179
</div>
167180

168181
<div className='counter-info'>
169-
<h4>Last Action: {state.lastAction}</h4>
170182
<h4>History:</h4>
171183
<div className='history-list'>
172184
{state.history.map((value, index) => (
@@ -178,7 +190,6 @@ function FunctionalReducerCounter({
178190
</div>
179191
</div>
180192

181-
{/* Secondary Counter Section */}
182193
<div
183194
className='secondary-counter'
184195
style={{ marginTop: '2rem', borderTop: '1px solid #ccc', paddingTop: '1rem' }}
@@ -201,8 +212,16 @@ function FunctionalReducerCounter({
201212
<button onClick={() => secondaryDispatch({ type: 'RESET' })}>Reset</button>
202213
</div>
203214
<div className='counter-info'>
204-
<h4>Last Operation: {secondaryState.lastOperation}</h4>
205215
<h4>Current Multiplier: {secondaryState.multiplier}</h4>
216+
<h4>History:</h4>
217+
<div className='history-list'>
218+
{secondaryState.history.map((value, index) => (
219+
<span key={index}>
220+
{value}
221+
{index < secondaryState.history.length - 1 ? ' → ' : ''}
222+
</span>
223+
))}
224+
</div>
206225
</div>
207226
</div>
208227
</div>

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ function FunctionalStateCounter({
8080
</div>
8181

8282
<div className='counter-info'>
83-
<h4>Last Action: {lastAction}</h4>
8483
<h4>History:</h4>
8584
<div className='history-list'>
8685
{history.map((value, index) => (

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ class ReducerCounter extends Component<CounterProps, CounterState> {
123123
</div>
124124

125125
<div className='counter-info'>
126-
<h4>Last Action: {this.state.lastAction}</h4>
127126
<h4>History:</h4>
128127
<div className='history-list'>
129128
{this.state.history.map((value, index) => (

src/backend/controllers/createTree.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -242,19 +242,13 @@ export default function createTree(currentFiberNode: Fiber): Tree {
242242
}
243243
}
244244
}
245-
246-
if (tag === ContextProvider) {
247-
// Extract context information
248-
console.log('ele', elementType);
249-
console.log('memo', memoizedState);
250-
const contextData = {
251-
displayName: elementType._context?.displayName || 'Anonymous Context',
252-
currentValue: memoizedState?.deps?.[0]?._currentValue || memoizedProps?.value,
253-
defaultValue: elementType._context?._defaultValue,
254-
consumers: [], // how do we track consumers?
255-
};
256-
257-
componentData.context = contextData;
245+
if (tag === ContextProvider && !elementType._context.displayName) {
246+
let stateData = memoizedProps.value;
247+
if (stateData === null || typeof stateData !== 'object') {
248+
stateData = { CONTEXT: stateData };
249+
}
250+
componentData.context = filterAndFormatData(stateData);
251+
componentName = 'Context';
258252
}
259253

260254
// -----------------ADD COMPONENT DATA TO THE OUTPUT TREE-------------------

src/backend/controllers/timeJump.ts

Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,21 @@ import { Status } from '../types/backendTypes';
33
import Tree from '../models/tree';
44
import { update } from 'lodash';
55

6-
// THIS FILE CONTAINS NECCESSARY FUNCTIONALITY FOR TIME-TRAVEL FEATURE
7-
8-
/**
9-
*
10-
* This is a closure function to keep track of mode (jumping or not jumping)
11-
* @param mode - The current mode (i.e. jumping)
12-
* @returns an async function that takes an `targetSnapshot`, then invokes `updateReactFiberTree` based on the state provided within that target snapshot
13-
*
14-
*/
156
export default function timeJumpInitiation(mode: Status) {
16-
/**
17-
* This function is to reset jumping mode to false when user hover the mouse over the browser body
18-
*/
197
const resetJumpingMode = (): void => {
208
mode.jumping = false;
219
};
22-
/**
23-
* This function that takes a `targetSnapshot` then invokes `updateReactFiberTree` to update the React Application on the browser to match states provided by the `targetSnapshot`
24-
* @param targetSnapshot - The target snapshot to re-render. The payload from index.ts is assigned to targetSnapshot
25-
*/
10+
2611
return async function timeJump(targetSnapshot: Tree): Promise<void> {
2712
mode.jumping = true;
28-
// Reset mode.navigating
2913
delete mode.navigating;
30-
// Traverse the snapshotTree to update ReactFiberTree
3114
updateReactFiberTree(targetSnapshot).then(() => {
32-
// Remove Event listener for mouse over
3315
document.removeEventListener('mouseover', resetJumpingMode);
34-
// Since in order to change state, user will need to navigate to browser
35-
// => set an event listener to resetJumpingMode when mouse is over the browser
3616
document.addEventListener('mouseover', resetJumpingMode, { once: true });
3717
});
3818
};
3919
}
4020

41-
/**
42-
* This recursive function receives the target snapshot from front end and will update the state of the fiber tree if the component is stateful
43-
* @param targetSnapshot - Target snapshot portrays some past state we want to travel to.
44-
* @param circularComponentTable - A table contains visited components
45-
*
46-
*/
4721
async function updateReactFiberTree(
4822
targetSnapshot,
4923
circularComponentTable: Set<any> = new Set(),
@@ -92,68 +66,21 @@ async function updateReactFiberTree(
9266
const reducer = functionalComponent[reducerIndex];
9367

9468
if (reducer?.dispatch) {
95-
console.log('Current reducer state:', {
96-
hookName,
97-
currentState: reducer.lastRenderedState,
98-
targetState,
99-
});
100-
101-
// Store original values
102-
const originalReducer = reducer.lastRenderedReducer;
103-
const originalState = reducer.lastRenderedState;
104-
10569
try {
106-
// Set the new state directly
107-
reducer.lastRenderedState = targetState;
108-
109-
// Override the reducer temporarily
110-
reducer.lastRenderedReducer = (state: any, action: any) => {
111-
if (action.type === '@@REACTIME/FORCE_STATE_UPDATE') {
112-
return action.payload;
113-
}
114-
return originalReducer ? originalReducer(state, action) : state;
115-
};
116-
117-
// Dispatch the force update action
118-
const forceUpdateAction = {
119-
type: '@@REACTIME/FORCE_STATE_UPDATE',
70+
// Use SET_STATE action to update the state
71+
const setStateAction = {
72+
type: 'SET_STATE',
12073
payload: targetState,
12174
};
12275

123-
await reducer.dispatch(forceUpdateAction);
124-
125-
console.log('Post-dispatch state:', {
126-
hookName,
127-
newState: reducer.lastRenderedState,
128-
success: JSON.stringify(reducer.lastRenderedState) === JSON.stringify(targetState),
129-
});
76+
await reducer.dispatch(setStateAction);
13077
} catch (error) {
13178
console.error('Error updating reducer state:', {
13279
hookName,
13380
error,
13481
componentName: targetSnapshot.name,
13582
});
136-
// Restore original state on error
137-
reducer.lastRenderedState = originalState;
138-
} finally {
139-
// Restore original reducer
140-
reducer.lastRenderedReducer = originalReducer;
141-
142-
console.log('Final reducer state check:', {
143-
hookName,
144-
originalState,
145-
targetState,
146-
finalState: reducer.lastRenderedState,
147-
stateMatchesTarget:
148-
JSON.stringify(reducer.lastRenderedState) === JSON.stringify(targetState),
149-
});
15083
}
151-
} else {
152-
console.warn('No dispatch found for reducer:', {
153-
hookName,
154-
reducerIndex,
155-
componentName: targetSnapshot.name,
156-
});
15784
}
15885
}
15986
}

0 commit comments

Comments
 (0)