Skip to content

Commit 6e1d675

Browse files
authored
Merge pull request #2025 from FaberVitale/fix/alm-update-counter-example
2 parents d1d9ef9 + 8e8676d commit 6e1d675

File tree

7 files changed

+77
-73
lines changed

7 files changed

+77
-73
lines changed

examples/action-listener/counter/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"private": true,
55
"dependencies": {
66
"@reduxjs/toolkit": "^1.6.0-rc.1",
7-
"@rtk-incubator/action-listener-middleware": "^0.6.0",
7+
"@rtk-incubator/action-listener-middleware": "^0.8.0",
88
"@types/node": "^12.0.0",
99
"@types/react": "^17.0.0",
1010
"@types/react-dom": "^17.0.0",
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import React, { useEffect } from 'react'
2+
import { Provider } from 'react-redux'
3+
import type { Unsubscribe } from '@reduxjs/toolkit'
4+
import { setupThemeListeners } from '../../services/theme/listeners'
5+
import { setupCounterListeners } from '../../services/counter/listeners'
6+
import { ChangeThemeForm } from '../ChangeThemeForm/ChangeThemeForm'
7+
import { CounterList } from '../CounterList/CounterList'
8+
import { CreateCounterForm } from '../CreateCounterForm/CreateCounterForm'
9+
import { store, startAppListening } from '../../store'
10+
11+
12+
export function App() {
13+
useEffect(() => {
14+
const subscriptions: Unsubscribe[] = [
15+
setupCounterListeners(startAppListening),
16+
setupThemeListeners(startAppListening),
17+
]
18+
19+
return () => subscriptions.forEach((unsubscribe) => unsubscribe())
20+
}, [])
21+
22+
return (
23+
<React.StrictMode>
24+
<Provider store={store}>
25+
<main className={'main'}>
26+
<header className="App-header">
27+
<h1>Counter example</h1>
28+
</header>
29+
<ChangeThemeForm />
30+
<CreateCounterForm />
31+
<CounterList />
32+
</main>
33+
</Provider>
34+
</React.StrictMode>
35+
)
36+
}
Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,11 @@
1-
import React from 'react'
21
import ReactDOM from 'react-dom'
32
import './index.css'
4-
import { Provider } from 'react-redux'
53
import { store } from './store'
64
import { themeActions } from './services/theme/slice'
7-
import { ChangeThemeForm } from './components/ChangeThemeForm/ChangeThemeForm'
8-
import { CounterList } from './components/CounterList/CounterList'
9-
import { CreateCounterForm } from './components/CreateCounterForm/CreateCounterForm'
5+
import { App } from './components/App/App'
106

117
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
128
store.dispatch(themeActions.changeColorScheme('dark'))
139
}
1410

15-
ReactDOM.render(
16-
<React.StrictMode>
17-
<Provider store={store}>
18-
<main className={'main'}>
19-
<header className="App-header">
20-
<h1>Counter example</h1>
21-
</header>
22-
<ChangeThemeForm />
23-
<CreateCounterForm />
24-
<CounterList />
25-
</main>
26-
</Provider>
27-
</React.StrictMode>,
28-
document.getElementById('root')
29-
)
11+
ReactDOM.render(<App />, document.getElementById('root'))

examples/action-listener/counter/src/services/counter/listeners.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { counterActions, counterSelectors } from './slice'
2-
import { AnyAction, isAllOf, isAnyOf, PayloadAction } from '@reduxjs/toolkit'
3-
import type { AppListenerApi, AppActionListenerMiddleware } from '../../store'
2+
import { AnyAction, isAllOf, isAnyOf, PayloadAction, Unsubscribe } from '@reduxjs/toolkit'
3+
import type { AppListenerEffectAPI, AppStartListening } from '../../store'
44

55
function shouldStopAsyncTasksOf(id: string) {
66
return isAllOf(
@@ -14,7 +14,7 @@ async function onUpdateByPeriodically(
1414
{
1515
payload: { id, delta },
1616
}: ReturnType<typeof counterActions.updateByPeriodically>,
17-
{ dispatch, getState, getOriginalState, condition }: AppListenerApi
17+
{ dispatch, getState, getOriginalState, condition }: AppListenerEffectAPI
1818
) {
1919
const counter = counterSelectors.selectById(getState(), id)
2020

@@ -44,7 +44,7 @@ async function onUpdateAsync(
4444
{
4545
payload: { id, delta, delayMs },
4646
}: ReturnType<typeof counterActions.updateByAsync>,
47-
{ condition, dispatch, getState }: AppListenerApi
47+
{ condition, dispatch, getState }: AppListenerEffectAPI
4848
) {
4949
const counter = counterSelectors.selectById(getState(), id)
5050

@@ -70,17 +70,15 @@ async function onUpdateAsync(
7070
* }, []);
7171
* ```
7272
*/
73-
export function setupCounterListeners(
74-
actionListener: AppActionListenerMiddleware
75-
) {
73+
export function setupCounterListeners(startListening: AppStartListening): Unsubscribe {
7674
const subscriptions = [
77-
actionListener.addListener({
75+
startListening({
7876
actionCreator: counterActions.updateByPeriodically,
79-
listener: onUpdateByPeriodically,
77+
effect: onUpdateByPeriodically,
8078
}),
81-
actionListener.addListener({
79+
startListening({
8280
actionCreator: counterActions.updateByAsync,
83-
listener: onUpdateAsync,
81+
effect: onUpdateAsync,
8482
}),
8583
]
8684

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
import { themeActions } from './slice'
2-
import type { AppActionListenerMiddleware } from '../../store'
2+
import type { AppStartListening } from '../../store'
3+
import { Unsubscribe } from '@reduxjs/toolkit'
34

45
function onChangeColorScheme(
56
action: ReturnType<typeof themeActions.changeColorScheme>
67
) {
7-
if (action.payload === 'light') {
8-
document.documentElement.classList.remove('dark')
9-
} else {
10-
document.documentElement.classList.add('dark')
11-
}
8+
document.documentElement.classList.toggle('dark', action.payload !== 'light')
129
}
1310

1411
export function setupThemeListeners(
15-
actionListener: AppActionListenerMiddleware
16-
) {
17-
return actionListener.addListener({
18-
actionCreator: themeActions.changeColorScheme,
19-
listener: onChangeColorScheme,
20-
})
12+
startListening: AppStartListening
13+
): Unsubscribe {
14+
const listeners = [
15+
startListening({
16+
actionCreator: themeActions.changeColorScheme,
17+
effect: onChangeColorScheme,
18+
}),
19+
]
20+
21+
return () => listeners.forEach((unsubscribe) => unsubscribe())
2122
}

examples/action-listener/counter/src/store.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
22
import { configureStore } from '@reduxjs/toolkit'
33
import { counterSlice } from './services/counter/slice'
44
import {
5-
createActionListenerMiddleware,
6-
ActionListenerMiddlewareAPI,
7-
ActionListenerMiddleware,
5+
createListenerMiddleware,
6+
TypedStartListening,
7+
TypedAddListener,
8+
ListenerEffectAPI,
9+
addListener,
810
} from '@rtk-incubator/action-listener-middleware'
911
import { themeSlice } from './services/theme/slice'
10-
import { setupCounterListeners } from './services/counter/listeners'
11-
import { setupThemeListeners } from './services/theme/listeners'
1212

13-
const actionListenerMiddleware = createActionListenerMiddleware({
13+
const listenerMiddlewareInstance = createListenerMiddleware({
1414
onError: () => console.error,
1515
})
1616

@@ -19,7 +19,7 @@ const store = configureStore({
1919
[counterSlice.name]: counterSlice.reducer,
2020
[themeSlice.name]: themeSlice.reducer,
2121
},
22-
middleware: (gDM) => gDM().prepend(actionListenerMiddleware),
22+
middleware: (gDM) => gDM().prepend(listenerMiddlewareInstance.middleware),
2323
})
2424

2525
export { store }
@@ -29,19 +29,15 @@ export type RootState = ReturnType<typeof store.getState>
2929
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
3030
export type AppDispatch = typeof store.dispatch
3131

32-
export type AppListenerApi = ActionListenerMiddlewareAPI<RootState, AppDispatch>
33-
export type AppActionListenerMiddleware = ActionListenerMiddleware<
34-
RootState,
35-
AppDispatch
36-
>
32+
export type AppListenerEffectAPI = ListenerEffectAPI<RootState, AppDispatch>
3733

38-
// Typed version of `actionListenerMiddleware`
39-
export const appActionListener =
40-
actionListenerMiddleware as AppActionListenerMiddleware
34+
export type AppStartListening = TypedStartListening<RootState>
35+
export type AppAddListener = TypedAddListener<RootState>
36+
37+
export const startAppListening =
38+
listenerMiddlewareInstance.startListening as AppStartListening
39+
export const addAppListener = addListener as AppAddListener
4140

4241
// Use throughout your app instead of plain `useDispatch` and `useSelector`
4342
export const useAppDispatch = () => useDispatch<AppDispatch>()
4443
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
45-
46-
setupCounterListeners(appActionListener)
47-
setupThemeListeners(appActionListener)

yarn.lock

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,7 +3673,7 @@ __metadata:
36733673
resolution: "@examples-action-listener/counter@workspace:examples/action-listener/counter"
36743674
dependencies:
36753675
"@reduxjs/toolkit": ^1.6.0-rc.1
3676-
"@rtk-incubator/action-listener-middleware": ^0.6.0
3676+
"@rtk-incubator/action-listener-middleware": ^0.8.0
36773677
"@types/node": ^12.0.0
36783678
"@types/react": ^17.0.0
36793679
"@types/react-dom": ^17.0.0
@@ -5513,16 +5513,7 @@ __metadata:
55135513
languageName: node
55145514
linkType: hard
55155515

5516-
"@rtk-incubator/action-listener-middleware@npm:^0.6.0":
5517-
version: 0.6.0
5518-
resolution: "@rtk-incubator/action-listener-middleware@npm:0.6.0"
5519-
peerDependencies:
5520-
"@reduxjs/toolkit": ^1.6.0
5521-
checksum: 01e600a9e513f883e4c6d02cbe4565b9691d6b43ebff432a9ad7f4f96d07c3164c3a0c14fde4391e3d3f65e18753e567b67d9645a2af27daba6b0aadd5fa2066
5522-
languageName: node
5523-
linkType: hard
5524-
5525-
"@rtk-incubator/action-listener-middleware@workspace:packages/action-listener-middleware":
5516+
"@rtk-incubator/action-listener-middleware@^0.8.0, @rtk-incubator/action-listener-middleware@workspace:packages/action-listener-middleware":
55265517
version: 0.0.0-use.local
55275518
resolution: "@rtk-incubator/action-listener-middleware@workspace:packages/action-listener-middleware"
55285519
dependencies:

0 commit comments

Comments
 (0)