Skip to content

Commit bc62c9e

Browse files
authored
Merge pull request #2024 from reduxjs/v1.8.0-integration
2 parents a620641 + 7cdd615 commit bc62c9e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2153
-1622
lines changed

.codesandbox/ci.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,11 @@
1212
"packages": [
1313
"packages/toolkit",
1414
"packages/rtk-query-graphql-request-base-query",
15-
"packages/action-listener-middleware",
1615
"packages/rtk-query-codegen-openapi"
1716
],
1817
"publishDirectory": {
1918
"@reduxjs/toolkit": "packages/toolkit",
2019
"@rtk-query/graphql-request-base-query": "packages/rtk-query-graphql-request-base-query",
21-
"@rtk-incubator/action-listener-middleware": "packages/action-listener-middleware",
2220
"@rtk-query/codegen-openapi": "packages/rtk-query-codegen-openapi"
2321
}
2422
}

.github/workflows/listenerTests.yml

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

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ jobs:
9696
fail-fast: false
9797
matrix:
9898
node: ['14.x']
99-
ts: ['3.9', '4.0', '4.1', '4.2', '4.3', '4.4', '4.5', 'next']
99+
ts: ['4.1', '4.2', '4.3', '4.4', '4.5', '4.6.1-rc', 'next']
100100
steps:
101101
- name: Checkout repo
102102
uses: actions/checkout@v2

docs/api/createListenerMiddleware.mdx

Lines changed: 701 additions & 0 deletions
Large diffs are not rendered by default.

examples/action-listener/counter/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
"version": "1.0.0",
44
"private": true,
55
"dependencies": {
6-
"@reduxjs/toolkit": "^1.6.0-rc.1",
7-
"@rtk-incubator/action-listener-middleware": "^0.6.0",
6+
"@reduxjs/toolkit": "^1.8.0-rc.0",
87
"@types/node": "^12.0.0",
98
"@types/react": "^17.0.0",
109
"@types/react-dom": "^17.0.0",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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+
export function App() {
12+
useEffect(() => {
13+
const subscriptions: Unsubscribe[] = [
14+
setupCounterListeners(startAppListening),
15+
setupThemeListeners(startAppListening),
16+
]
17+
18+
return () => subscriptions.forEach((unsubscribe) => unsubscribe())
19+
}, [])
20+
21+
return (
22+
<React.StrictMode>
23+
<Provider store={store}>
24+
<main className={'main'}>
25+
<header className="App-header">
26+
<h1>Counter example</h1>
27+
</header>
28+
<ChangeThemeForm />
29+
<CreateCounterForm />
30+
<CounterList />
31+
</main>
32+
</Provider>
33+
</React.StrictMode>
34+
)
35+
}
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: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { counterActions, counterSelectors } from './slice'
2-
import { AnyAction, isAllOf, isAnyOf, PayloadAction } from '@reduxjs/toolkit'
3-
import type { AppListenerApi, AppActionListenerMiddleware } from '../../store'
2+
import {
3+
AnyAction,
4+
isAllOf,
5+
isAnyOf,
6+
PayloadAction,
7+
Unsubscribe,
8+
} from '@reduxjs/toolkit'
9+
import type { AppListenerEffectAPI, AppStartListening } from '../../store'
410

511
function shouldStopAsyncTasksOf(id: string) {
612
return isAllOf(
@@ -14,7 +20,7 @@ async function onUpdateByPeriodically(
1420
{
1521
payload: { id, delta },
1622
}: ReturnType<typeof counterActions.updateByPeriodically>,
17-
{ dispatch, getState, getOriginalState, condition }: AppListenerApi
23+
{ dispatch, getState, getOriginalState, condition }: AppListenerEffectAPI
1824
) {
1925
const counter = counterSelectors.selectById(getState(), id)
2026

@@ -44,7 +50,7 @@ async function onUpdateAsync(
4450
{
4551
payload: { id, delta, delayMs },
4652
}: ReturnType<typeof counterActions.updateByAsync>,
47-
{ condition, dispatch, getState }: AppListenerApi
53+
{ condition, dispatch, getState }: AppListenerEffectAPI
4854
) {
4955
const counter = counterSelectors.selectById(getState(), id)
5056

@@ -71,16 +77,16 @@ async function onUpdateAsync(
7177
* ```
7278
*/
7379
export function setupCounterListeners(
74-
actionListener: AppActionListenerMiddleware
75-
) {
80+
startListening: AppStartListening
81+
): Unsubscribe {
7682
const subscriptions = [
77-
actionListener.addListener({
83+
startListening({
7884
actionCreator: counterActions.updateByPeriodically,
79-
listener: onUpdateByPeriodically,
85+
effect: onUpdateByPeriodically,
8086
}),
81-
actionListener.addListener({
87+
startListening({
8288
actionCreator: counterActions.updateByAsync,
83-
listener: onUpdateAsync,
89+
effect: onUpdateAsync,
8490
}),
8591
]
8692

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
}
Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
2-
import { configureStore } from '@reduxjs/toolkit'
3-
import { counterSlice } from './services/counter/slice'
42
import {
5-
createActionListenerMiddleware,
6-
ActionListenerMiddlewareAPI,
7-
ActionListenerMiddleware,
8-
} from '@rtk-incubator/action-listener-middleware'
3+
configureStore,
4+
createListenerMiddleware,
5+
TypedStartListening,
6+
TypedAddListener,
7+
ListenerEffectAPI,
8+
addListener,
9+
} from '@reduxjs/toolkit'
10+
import { counterSlice } from './services/counter/slice'
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)

0 commit comments

Comments
 (0)