Skip to content

Commit 3496f3c

Browse files
committed
fix: dispatch operations are now untracked
1 parent 233f9d8 commit 3496f3c

File tree

11 files changed

+190
-4
lines changed

11 files changed

+190
-4
lines changed

angular.json

+69
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,75 @@
190190
"builder": "@angular-devkit/build-angular:extract-i18n"
191191
}
192192
}
193+
},
194+
"angular-redux-auto-dispatch-demo": {
195+
"projectType": "application",
196+
"schematics": {},
197+
"root": "projects/angular-redux-auto-dispatch-demo",
198+
"sourceRoot": "projects/angular-redux-auto-dispatch-demo/src",
199+
"prefix": "app",
200+
"architect": {
201+
"build": {
202+
"builder": "@angular-devkit/build-angular:application",
203+
"options": {
204+
"outputPath": "dist/angular-redux-auto-dispatch-demo",
205+
"index": "projects/angular-redux-auto-dispatch-demo/src/index.html",
206+
"browser": "projects/angular-redux-auto-dispatch-demo/src/main.ts",
207+
"polyfills": [
208+
"zone.js"
209+
],
210+
"tsConfig": "projects/angular-redux-auto-dispatch-demo/tsconfig.app.json",
211+
"assets": [
212+
{
213+
"glob": "**/*",
214+
"input": "projects/angular-redux-auto-dispatch-demo/public"
215+
}
216+
],
217+
"styles": [
218+
"projects/angular-redux-auto-dispatch-demo/src/styles.css"
219+
],
220+
"scripts": []
221+
},
222+
"configurations": {
223+
"production": {
224+
"budgets": [
225+
{
226+
"type": "initial",
227+
"maximumWarning": "500kB",
228+
"maximumError": "1MB"
229+
},
230+
{
231+
"type": "anyComponentStyle",
232+
"maximumWarning": "4kB",
233+
"maximumError": "8kB"
234+
}
235+
],
236+
"outputHashing": "all"
237+
},
238+
"development": {
239+
"optimization": false,
240+
"extractLicenses": false,
241+
"sourceMap": true
242+
}
243+
},
244+
"defaultConfiguration": "production"
245+
},
246+
"serve": {
247+
"builder": "@angular-devkit/build-angular:dev-server",
248+
"configurations": {
249+
"production": {
250+
"buildTarget": "angular-redux-auto-dispatch-demo:build:production"
251+
},
252+
"development": {
253+
"buildTarget": "angular-redux-auto-dispatch-demo:build:development"
254+
}
255+
},
256+
"defaultConfiguration": "development"
257+
},
258+
"extract-i18n": {
259+
"builder": "@angular-devkit/build-angular:extract-i18n"
260+
}
261+
}
193262
}
194263
}
195264
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Component, effect } from '@angular/core';
2+
import { injectSelector, injectDispatch } from '@reduxjs/angular-redux';
3+
import { decrement, increment } from './store/counter-slice';
4+
import { RootState } from './store';
5+
6+
@Component({
7+
selector: 'app-root',
8+
standalone: true,
9+
template: `
10+
<button (click)="dispatch(increment())">Increment</button>
11+
<span>{{ count() }}</span>
12+
<button (click)="dispatch(decrement())">Decrement</button>
13+
`,
14+
})
15+
export class AppComponent {
16+
count = injectSelector((state: RootState) => state.counter.value);
17+
dispatch = injectDispatch();
18+
increment = increment;
19+
decrement = decrement;
20+
21+
_auto_increment = effect(() => {
22+
this.dispatch(increment());
23+
});
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
2+
import { provideRedux } from '@reduxjs/angular-redux';
3+
import { store } from './store';
4+
5+
export const appConfig: ApplicationConfig = {
6+
providers: [
7+
provideZoneChangeDetection({ eventCoalescing: true }),
8+
provideRedux({ store }),
9+
],
10+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { createSlice } from '@reduxjs/toolkit';
2+
import type { PayloadAction } from '@reduxjs/toolkit';
3+
4+
export interface CounterState {
5+
value: number;
6+
}
7+
8+
const initialState: CounterState = {
9+
value: 0,
10+
};
11+
12+
export const counterSlice = createSlice({
13+
name: 'counter',
14+
initialState,
15+
reducers: {
16+
increment: (state) => {
17+
// Redux Toolkit allows us to write "mutating" logic in reducers. It
18+
// doesn't actually mutate the state because it uses the Immer library,
19+
// which detects changes to a "draft state" and produces a brand new
20+
// immutable state based off those changes
21+
state.value += 1;
22+
},
23+
decrement: (state) => {
24+
state.value -= 1;
25+
},
26+
incrementByAmount: (state, action: PayloadAction<number>) => {
27+
state.value += action.payload;
28+
},
29+
},
30+
});
31+
32+
// Action creators are generated for each case reducer function
33+
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
34+
35+
export default counterSlice.reducer;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { configureStore } from '@reduxjs/toolkit';
2+
import counterReducer from './counter-slice';
3+
4+
export const store = configureStore({
5+
reducer: {
6+
counter: counterReducer,
7+
},
8+
});
9+
10+
// Infer the `RootState` and `AppDispatch` types from the store itself
11+
export type RootState = ReturnType<typeof store.getState>;
12+
// Inferred type: {counter: CounterState}
13+
export type AppDispatch = typeof store.dispatch;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>AngularReduxDemo</title>
6+
<base href="/" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1" />
8+
<link rel="icon" type="image/x-icon" href="favicon.ico" />
9+
</head>
10+
<body>
11+
<app-root></app-root>
12+
</body>
13+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { bootstrapApplication } from '@angular/platform-browser';
2+
import { appConfig } from './app/app.config';
3+
import { AppComponent } from './app/app.component';
4+
5+
bootstrapApplication(AppComponent, appConfig).catch((err) =>
6+
console.error(err),
7+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* You can add global styles to this file, and also import other style files */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
2+
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
3+
{
4+
"extends": "../../tsconfig.json",
5+
"compilerOptions": {
6+
"outDir": "../../out-tsc/app",
7+
"types": []
8+
},
9+
"files": [
10+
"src/main.ts"
11+
],
12+
"include": [
13+
"src/**/*.d.ts"
14+
]
15+
}

projects/angular-redux/src/lib/inject-selector.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,12 @@ export function createSelectorInjection(): InjectSelector {
9191

9292
const { store, subscription } = reduxContext;
9393

94-
const selectedState = linkedSignal(() => selector(store.getState()));
94+
const selectedState = linkedSignal(() => selector(store.getState()), {
95+
equal: equalityFn,
96+
});
9597

9698
const unsubscribe = subscription.addNestedSub(() => {
9799
const data = selector(store.getState());
98-
if (equalityFn(selectedState(), data)) {
99-
return;
100-
}
101100

102101
selectedState.set(data);
103102
});

0 commit comments

Comments
 (0)