Skip to content

Commit 45f567c

Browse files
committed
Merge branch 'master' of https://github.com/reduxjs/react-redux into format-all-files
2 parents ca4bfd3 + 822f5c9 commit 45f567c

Some content is hidden

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

47 files changed

+4837
-4613
lines changed

.eslintrc.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
},
2424
"settings": {
2525
"import/ignore": ["react-native"],
26-
"import/resolver": { "node": { "extensions": [".js", ".ts", ".tsx"] } },
26+
"import/resolver": {
27+
"typescript": { "extensions": [".js", ".ts", ".tsx"] }
28+
},
2729
"react": { "version": "detect" }
2830
},
2931
"overrides": [
@@ -33,6 +35,7 @@
3335
"eslint:recommended",
3436
"plugin:import/recommended",
3537
"plugin:react/recommended",
38+
"plugin:react/jsx-runtime",
3639
"plugin:@typescript-eslint/recommended"
3740
],
3841
"rules": {
@@ -56,7 +59,7 @@
5659
},
5760
{
5861
"files": ["**/test/**/*.{ts,tsx}"],
59-
"parserOptions": { "project": "./test/tsconfig.test.json" }
62+
"parserOptions": { "project": true }
6063
}
6164
]
6265
}

.github/workflows/test.yml

+61-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
name: Tests
22

3-
on:
4-
push:
5-
branches: [master]
6-
pull_request:
7-
branches: [master]
8-
workflow_dispatch:
3+
on: [push, pull_request, workflow_dispatch]
94

105
jobs:
116
build:
12-
name: Test Suite
7+
name: Build and run test Suite
138
runs-on: ubuntu-latest
149

1510
steps:
@@ -25,6 +20,9 @@ jobs:
2520
- name: Install dependencies
2621
run: yarn install
2722

23+
- name: Lint
24+
run: yarn lint
25+
2826
- name: Run test suite
2927
run: yarn test
3028

@@ -63,13 +61,27 @@ jobs:
6361
node-version: ${{ matrix.node }}
6462
cache: 'yarn'
6563

64+
- name: Download build artifact
65+
uses: actions/download-artifact@v4
66+
with:
67+
name: package
68+
path: .
69+
6670
- name: Install deps
6771
run: yarn install
6872

6973
- name: Install TypeScript ${{ matrix.ts }}
7074
run: yarn add typescript@${{ matrix.ts }}
7175

76+
- name: Install build artifact
77+
run: yarn add ./package.tgz
78+
79+
- name: Erase path aliases
80+
run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json
81+
7282
- name: Test types
83+
env:
84+
TEST_DIST: true
7385
run: |
7486
yarn tsc --version
7587
yarn type-tests
@@ -93,10 +105,8 @@ jobs:
93105
path: .
94106

95107
# Note: We currently expect "FalseCJS" failures for Node16 + `moduleResolution: "node16",
96-
# and the `/alternateRenderers" entry point will not resolve under Node10.
97-
# Skipping these is dangerous, but we'll leave it for now.
98108
- name: Run are-the-types-wrong
99-
run: npx @arethetypeswrong/cli ./package.tgz --format table --ignore-rules false-cjs no-resolution
109+
run: npx @arethetypeswrong/cli ./package.tgz --format table --ignore-rules false-cjs --exclude-entrypoints alternate-renderers
100110

101111
test-published-artifact:
102112
name: Test Published Artifact ${{ matrix.example }}
@@ -221,3 +231,44 @@ jobs:
221231

222232
- name: Build example
223233
run: yarn build
234+
235+
test-dist:
236+
name: Run local tests against build artifact
237+
needs: [build]
238+
runs-on: ubuntu-latest
239+
strategy:
240+
fail-fast: false
241+
matrix:
242+
node: ['20.x']
243+
steps:
244+
- name: Checkout repo
245+
uses: actions/checkout@v4
246+
247+
- name: Use node ${{ matrix.node }}
248+
uses: actions/setup-node@v4
249+
with:
250+
node-version: ${{ matrix.node }}
251+
cache: 'yarn'
252+
253+
- name: Install deps
254+
run: yarn install
255+
256+
- name: Download build artifact
257+
uses: actions/download-artifact@v4
258+
with:
259+
name: package
260+
path: .
261+
262+
- name: Check folder contents
263+
run: ls -lah
264+
265+
- name: Install build artifact
266+
run: yarn add ./package.tgz
267+
268+
- name: Erase path aliases
269+
run: sed -i -e /@remap-prod-remove-line/d ./tsconfig.base.json
270+
271+
- name: Run local tests against the build artifact
272+
env:
273+
TEST_DIST: true
274+
run: yarn test

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,6 @@ website/translated_docs
3232
website/build/
3333
website/node_modules
3434
website/i18n/*
35+
36+
tsconfig.vitest-temp.json
37+

docs/api/hooks.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ interface UseSelectorOptions {
5959
}
6060

6161
const result: Selected = useSelector(
62-
selector: SelectorFunction,
62+
selector: SelectorFn,
6363
options?: EqualityFn | UseSelectorOptions
6464
)
6565
```

docs/using-react-redux/accessing-store.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ store interaction is handled. In typical usage, your own components should never
1717
won't ever reference the store directly. React Redux also internally handles the details of how the store and state are
1818
propagated to connected components, so that this works as expected by default.
1919

20-
However, there may be certain use cases where you may need to customize how the store and state are propagated to
20+
However, there may be certain use cases where you may need to customize how the store is passed to
2121
connected components, or access the store directly. Here are some examples of how to do this.
2222

2323
## Understanding Context Usage
@@ -26,8 +26,7 @@ Internally, React Redux uses [React's "context" feature](https://react.dev/learn
2626
Redux store accessible to deeply nested connected components. As of React Redux version 6, this is normally handled
2727
by a single default context object instance generated by `React.createContext()`, called `ReactReduxContext`.
2828

29-
React Redux's `<Provider>` component uses `<ReactReduxContext.Provider>` to put the Redux store and the current store
30-
state into context, and `connect` uses `useContext(ReactReduxContext)` to read those values and handle updates.
29+
React Redux's `<Provider>` component uses `<ReactReduxContext.Provider>` to put the Redux store and internal subscription wrappers into context. `useSelector`, `useDispatch`, and `connect` call `useContext(ReactReduxContext)` to read those values and handle updates.
3130

3231
## Using the `useStore` Hook
3332

package.json

+42-45
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-redux",
3-
"version": "9.1.0",
3+
"version": "9.1.2",
44
"description": "Official React bindings for Redux",
55
"keywords": [
66
"react",
@@ -36,79 +36,76 @@
3636
"dist"
3737
],
3838
"scripts": {
39-
"build": "tsup",
39+
"build": "yarn clean && tsup",
4040
"clean": "rimraf lib dist es coverage",
4141
"api-types": "api-extractor run --local",
4242
"format": "prettier --write \"{src,test}/**/*.{js,ts,tsx}\" \"docs/**/*.md\"",
4343
"lint": "eslint src test",
4444
"lint:fix": "eslint src test --fix",
4545
"prepare": "yarn clean && yarn build",
4646
"pretest": "yarn lint",
47-
"test": "vitest --run",
47+
"test": "vitest --run --typecheck",
4848
"test:watch": "vitest --watch",
49-
"type-tests": "yarn tsc -p test/typetests/tsconfig.json",
49+
"type-tests": "tsc --noEmit -p tsconfig.test.json",
5050
"coverage": "codecov"
5151
},
5252
"peerDependencies": {
5353
"@types/react": "^18.2.25",
5454
"react": "^18.0",
55-
"react-native": ">=0.69",
5655
"redux": "^5.0.0"
5756
},
5857
"peerDependenciesMeta": {
5958
"@types/react": {
6059
"optional": true
6160
},
62-
"react-native": {
63-
"optional": true
64-
},
6561
"redux": {
6662
"optional": true
6763
}
6864
},
6965
"dependencies": {
70-
"@types/use-sync-external-store": "^0.0.3",
71-
"use-sync-external-store": "^1.0.0"
66+
"@types/use-sync-external-store": "^0.0.6",
67+
"use-sync-external-store": "^1.2.2"
7268
},
7369
"devDependencies": {
74-
"@babel/cli": "^7.12.1",
75-
"@babel/core": "^7.12.3",
76-
"@babel/plugin-proposal-decorators": "^7.12.1",
77-
"@babel/plugin-proposal-object-rest-spread": "^7.12.1",
78-
"@babel/plugin-transform-flow-strip-types": "^7.22.5",
79-
"@babel/plugin-transform-react-display-name": "^7.12.1",
80-
"@babel/plugin-transform-react-jsx": "^7.12.1",
81-
"@babel/plugin-transform-runtime": "^7.12.1",
82-
"@babel/preset-env": "^7.12.1",
83-
"@babel/preset-typescript": "^7.14.5",
84-
"@microsoft/api-extractor": "^7.18.1",
85-
"@reduxjs/toolkit": "^2.0.0-beta.4",
86-
"@testing-library/jest-dom": "^6.3.0",
87-
"@testing-library/react": "^14.1.2",
88-
"@testing-library/react-hooks": "^8.0.1",
89-
"@types/node": "^20.11.6",
90-
"@types/react": "18.2.25",
91-
"@typescript-eslint/eslint-plugin": "^6.17.0",
92-
"@typescript-eslint/parser": "^6.17.0",
70+
"@babel/cli": "^7.24.7",
71+
"@babel/core": "^7.24.7",
72+
"@babel/plugin-proposal-decorators": "^7.24.7",
73+
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
74+
"@babel/plugin-transform-flow-strip-types": "^7.24.7",
75+
"@babel/plugin-transform-react-display-name": "^7.24.7",
76+
"@babel/plugin-transform-react-jsx": "^7.24.7",
77+
"@babel/plugin-transform-runtime": "^7.24.7",
78+
"@babel/preset-env": "^7.24.7",
79+
"@babel/preset-typescript": "^7.24.7",
80+
"@microsoft/api-extractor": "^7.47.0",
81+
"@reduxjs/toolkit": "^2.2.5",
82+
"@testing-library/dom": "^10.1.0",
83+
"@testing-library/jest-dom": "^6.4.5",
84+
"@testing-library/react": "^16.0.0",
85+
"@types/node": "^20.14.2",
86+
"@types/prop-types": "^15.7.12",
87+
"@types/react": "18.3.3",
88+
"@types/react-dom": "^18.3.0",
9389
"babel-eslint": "^10.1.0",
94-
"codecov": "^3.8.0",
95-
"cross-env": "^7.0.2",
96-
"eslint": "^8.56.0",
90+
"codecov": "^3.8.3",
91+
"cross-env": "^7.0.3",
92+
"eslint": "^8.57.0",
9793
"eslint-config-prettier": "^9.1.0",
94+
"eslint-import-resolver-typescript": "^3.6.1",
9895
"eslint-plugin-import": "^2.29.1",
99-
"eslint-plugin-prettier": "^5.1.2",
100-
"eslint-plugin-react": "^7.33.2",
101-
"glob": "^7.1.6",
102-
"jsdom": "^24.0.0",
103-
"prettier": "^3.2.5",
104-
"react": "18.2.0",
105-
"react-dom": "18.2.0",
106-
"react-test-renderer": "18.0.0",
107-
"redux": "^5.0.0",
108-
"rimraf": "^3.0.2",
109-
"tsup": "^7.0.0",
110-
"typescript": "^5.4.2",
111-
"vitest": "^1.2.1"
96+
"eslint-plugin-prettier": "^5.1.3",
97+
"eslint-plugin-react": "^7.34.2",
98+
"jsdom": "^24.1.0",
99+
"prettier": "^3.3.1",
100+
"react": "18.3.1",
101+
"react-dom": "18.3.1",
102+
"react-test-renderer": "18.3.1",
103+
"redux": "^5.0.1",
104+
"rimraf": "^5.0.7",
105+
"tsup": "7.0.0",
106+
"typescript": "^5.4.5",
107+
"typescript-eslint": "^7.12.0",
108+
"vitest": "^1.6.0"
112109
},
113110
"packageManager": "[email protected]"
114111
}

src/components/Provider.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ function Provider<A extends Action<string> = UnknownAction, S = unknown>({
9191

9292
const Context = context || ReactReduxContext
9393

94-
// @ts-ignore 'AnyAction' is assignable to the constraint of type 'A', but 'A' could be instantiated with a different subtype
9594
return <Context.Provider value={contextValue}>{children}</Context.Provider>
9695
}
9796

src/components/connect.tsx

+9-4
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,6 @@ function connect<
519519
WrappedComponent,
520520
// @ts-ignore
521521
initMapStateToProps,
522-
// @ts-ignore
523522
initMapDispatchToProps,
524523
initMergeProps,
525524
areStatesEqual,
@@ -641,13 +640,19 @@ function connect<
641640
}, [didStoreComeFromProps, contextValue, subscription])
642641

643642
// Set up refs to coordinate values between the subscription effect and the render logic
644-
const lastChildProps = React.useRef<unknown>()
643+
const lastChildProps = React.useRef<unknown>(undefined)
645644
const lastWrapperProps = React.useRef(wrapperProps)
646-
const childPropsFromStoreUpdate = React.useRef<unknown>()
645+
const childPropsFromStoreUpdate = React.useRef<unknown>(undefined)
647646
const renderIsScheduled = React.useRef(false)
648647
const isMounted = React.useRef(false)
649648

650-
const latestSubscriptionCallbackError = React.useRef<Error>()
649+
// TODO: Change this to `React.useRef<Error>(undefined)` after upgrading to React 19.
650+
/**
651+
* @todo Change this to `React.useRef<Error>(undefined)` after upgrading to React 19.
652+
*/
653+
const latestSubscriptionCallbackError = React.useRef<Error | undefined>(
654+
undefined,
655+
)
651656

652657
useIsomorphicLayoutEffect(() => {
653658
isMounted.current = true

src/hooks/useSelector.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export function createSelectorHook(
142142
? useDefaultReduxContext
143143
: createReduxContextHook(context)
144144

145-
const useSelector = <TState, Selected extends unknown>(
145+
const useSelector = <TState, Selected>(
146146
selector: (state: TState) => Selected,
147147
equalityFnOrOptions:
148148
| EqualityFn<NoInfer<Selected>>

src/index-rsc.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,25 @@ const _check2: typeof rsc = {} as typeof normal
1010

1111
// -------------------------------------------------------------------------------------
1212

13-
function throwNotSupportedError(
13+
const throwNotSupportedError = ((
1414
// eslint-disable-next-line @typescript-eslint/no-unused-vars
1515
...args: any[]
16-
): any {
16+
): any => {
1717
throw new Error(
1818
'This function is not supported in React Server Components. Please only use this export in a Client Component.',
1919
)
20-
}
20+
}) as any
2121

2222
export {
23-
throwNotSupportedError as batch,
2423
throwNotSupportedError as Provider,
24+
throwNotSupportedError as batch,
2525
throwNotSupportedError as connect,
26-
throwNotSupportedError as useSelector,
27-
throwNotSupportedError as useDispatch,
28-
throwNotSupportedError as useStore,
2926
throwNotSupportedError as createDispatchHook,
3027
throwNotSupportedError as createSelectorHook,
3128
throwNotSupportedError as createStoreHook,
29+
throwNotSupportedError as useDispatch,
30+
throwNotSupportedError as useSelector,
31+
throwNotSupportedError as useStore,
3232
}
3333
export const ReactReduxContext = {} as any
3434
export { default as shallowEqual } from './utils/shallowEqual'

src/utils/react.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import * as ReactOriginal from 'react'
21
import type * as ReactNamespace from 'react'
2+
import * as ReactOriginal from 'react'
33

44
export const React: typeof ReactNamespace =
55
// prettier-ignore
6-
// @ts-ignore
76
'default' in ReactOriginal ? ReactOriginal['default'] : ReactOriginal as any

0 commit comments

Comments
 (0)