Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example of lazy loading slices with combineSlices, and middleware with createDynamicMiddleware #4064

Open
wants to merge 62 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
2efb023
clone vite example
EskiMojo14 Jan 10, 2024
ba37b29
lazy load all the things
EskiMojo14 Jan 10, 2024
db7086d
Fix App test
EskiMojo14 Jan 11, 2024
494d7df
Add non-lazy todo example
EskiMojo14 Jan 11, 2024
5b1138c
add comment for type mismatch
EskiMojo14 Jan 11, 2024
67f4c92
add example of createAppDispatchWithMiddlewareHook
EskiMojo14 Jan 11, 2024
f0ace1b
add log when middleware initialises
EskiMojo14 Jan 11, 2024
4fd828a
use react-lazily for named exports
EskiMojo14 Jan 11, 2024
daedb89
make getCount in slice
EskiMojo14 Jan 11, 2024
bec2ed5
fix import
EskiMojo14 Jan 11, 2024
2ac362f
save inject result to variable
EskiMojo14 Jan 11, 2024
0bd1139
added .selector example
EskiMojo14 Jan 11, 2024
04b0a8b
add comment re: duplication
EskiMojo14 Jan 11, 2024
cefbf1c
add comment re: react-lazily
EskiMojo14 Jan 12, 2024
1b3cbd8
golf
EskiMojo14 Jan 12, 2024
7c4387f
try adding lazy injection example to sandboxes
EskiMojo14 Jan 12, 2024
81aa3a7
bump CSB node to 18
EskiMojo14 Jan 12, 2024
1e4363c
remove open: true
EskiMojo14 Jan 12, 2024
99253f7
use withTypes hooks
EskiMojo14 Jan 14, 2024
844baec
enable consistent type imports rule
EskiMojo14 Jan 14, 2024
834f6d1
move todos below add field
EskiMojo14 Jan 14, 2024
d8aa0db
add comment slice to demonstrate linked normalized state
EskiMojo14 Jan 14, 2024
4df4670
Rename example to kitchen-sink
EskiMojo14 Jan 14, 2024
60068d6
update lockfile
EskiMojo14 Jan 14, 2024
a011ea5
Add comment slice tests
EskiMojo14 Jan 14, 2024
cd18280
Update examples/lazy-injection/kitchen-sink/src/features/todos/commen…
EskiMojo14 Jan 14, 2024
77f4f95
Use different build of RTK
EskiMojo14 Jan 15, 2024
0c32773
ensure reselect 5.1 and demo .withTypes
EskiMojo14 Jan 15, 2024
73820b5
add withTypes to createDraftSafeSelector
EskiMojo14 Jan 15, 2024
785eed7
fix ci settings
EskiMojo14 Jan 15, 2024
38f2213
Merge branch 'master' into combineslices-example
EskiMojo14 Jan 15, 2024
3bf655b
remove unnecessary casts
EskiMojo14 Jan 15, 2024
7df80d5
pass localised selectors to createSlice
EskiMojo14 Jan 15, 2024
686205a
lazy load comments
EskiMojo14 Jan 15, 2024
1b375ab
add tabs
EskiMojo14 Jan 15, 2024
39c3380
make button size consistent
EskiMojo14 Jan 15, 2024
c9dce74
undo changes to hook file for the sake of argument
EskiMojo14 Jan 17, 2024
5d87dd3
format buildHooks just to prove it still fails
EskiMojo14 Jan 17, 2024
c969d80
why does this work
EskiMojo14 Jan 17, 2024
afb8b7c
use RTL 13
EskiMojo14 Jan 17, 2024
4ae92fc
Bump `@testing-library/react` dev dependency
aryaemami59 Jan 18, 2024
34a617a
Add @testing-library/react as a dev dependency
aryaemami59 Jan 18, 2024
8f035c8
Merge branch 'master' into combineslices-example
EskiMojo14 Jan 18, 2024
25a813e
Merge branch 'master' of https://github.com/reduxjs/redux-toolkit int…
aryaemami59 Jan 18, 2024
295ccec
Update lockfile
aryaemami59 Jan 18, 2024
ddacd0a
Merge branch 'combineslices-example' of https://github.com/reduxjs/re…
aryaemami59 Jan 18, 2024
f285dbe
Merge pull request #4092 from aryaemami59/combineslices-example
EskiMojo14 Jan 18, 2024
976abfb
Merge branch 'master' into combineslices-example
EskiMojo14 Jan 29, 2024
e97fed0
run prettier
EskiMojo14 Jan 29, 2024
1c12ef2
Merge branch 'master' into combineslices-example
EskiMojo14 Feb 5, 2024
8fa9ea8
Merge branch 'master' into combineslices-example
EskiMojo14 Feb 5, 2024
4f78d48
Merge branch 'master' into combineslices-example
EskiMojo14 Feb 5, 2024
248ca9f
Merge branch 'master' into combineslices-example
EskiMojo14 Feb 21, 2024
339ec04
Merge branch 'master' into combineslices-example
EskiMojo14 Apr 17, 2024
cc3d827
use a let for store instead of test context
EskiMojo14 Apr 17, 2024
b13943a
update prettier 2 resolution
EskiMojo14 Apr 17, 2024
fd8f9bb
move note regarding using original createSlice
EskiMojo14 Apr 17, 2024
40cdc44
Merge branch 'master' into combineslices-example
EskiMojo14 Jun 19, 2024
942f2f0
Merge branch 'master' into combineslices-example
EskiMojo14 Sep 1, 2024
ec5d2b2
Merge branch 'master' into combineslices-example
EskiMojo14 Oct 25, 2024
dd45e4e
Merge branch 'master' into combineslices-example
EskiMojo14 Nov 18, 2024
a39d645
Merge branch 'master' into combineslices-example
EskiMojo14 Nov 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"/examples/query/react/basic",
"/examples/query/react/advanced",
"/examples/action-listener/counter",
"/examples/lazy-injection/counter-todo",
"/examples/publish-ci/cra5"
],
"node": "16",
"node": "18",
"buildCommand": "build:packages",
"packages": [
"packages/toolkit",
Expand Down
17 changes: 17 additions & 0 deletions examples/lazy-injection/counter-todo/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"extends": ["react-app"],
"rules": {
"@typescript-eslint/no-restricted-imports": [
2,
{
"paths": [
{
"name": "react-redux",
"importNames": ["useSelector", "useStore", "useDispatch"],
"message": "Please use pre-typed versions from `src/app/hooks.ts` instead."
}
]
}
]
}
}
30 changes: 30 additions & 0 deletions examples/lazy-injection/counter-todo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# Dependencies
node_modules
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Swap the comments on the following lines if you don't wish to use zero-installs
# Documentation here: https://yarnpkg.com/features/zero-installs
!.yarn/cache
#.pnp.*

# Testing
coverage

# Production
build

# Miscellaneous
*.local
4 changes: 4 additions & 0 deletions examples/lazy-injection/counter-todo/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"semi": false,
"arrowParens": "avoid"
}
27 changes: 27 additions & 0 deletions examples/lazy-injection/counter-todo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# vite-template-redux

Uses [Vite](https://vitejs.dev/), [Vitest](https://vitest.dev/), and [React Testing Library](https://github.com/testing-library/react-testing-library) to create a modern [React](https://react.dev/) app compatible with [Create React App](https://create-react-app.dev/)

```sh
npx degit reduxjs/redux-templates/packages/vite-template-redux my-app
```

## Goals

- Easy migration from Create React App or Vite
- As beginner friendly as Create React App
- Optimized performance compared to Create React App
- Customizable without ejecting

## Scripts

- `dev`/`start` - start dev server and open browser
- `build` - build for production
- `preview` - locally preview production build
- `test` - launch test runner

## Inspiration

- [Create React App](https://github.com/facebook/create-react-app/tree/main/packages/cra-template)
- [Vite](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react)
- [Vitest](https://github.com/vitest-dev/vitest/tree/main/examples/react-testing-lib)
14 changes: 14 additions & 0 deletions examples/lazy-injection/counter-todo/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>React Redux App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
42 changes: 42 additions & 0 deletions examples/lazy-injection/counter-todo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "@examples-lazy-injection/counter-todo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"start": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest watch",
"format": "prettier --write .",
"lint": "eslint .",
"type-check": "tsc"
},
"dependencies": {
"@reduxjs/toolkit": "https://pkg.csb.dev/reduxjs/redux-toolkit/commit/4fe0b237/@reduxjs/toolkit/_pkg.tgz",
"clsx": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-lazily": "^0.9.2",
"react-redux": "^9.0.4"
},
"devDependencies": {
"@testing-library/dom": "^9.3.3",
"@testing-library/jest-dom": "^6.1.6",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
"@types/react": "^18.2.46",
"@types/react-dom": "^18.2.18",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.56.0",
"eslint-config-react-app": "^7.0.1",
"eslint-plugin-prettier": "^5.1.2",
"jsdom": "^23.0.1",
"prettier": "^3.1.1",
"typescript": "^5.3.3",
"vite": "^5.0.10",
"vitest": "^1.1.1"
}
}
39 changes: 39 additions & 0 deletions examples/lazy-injection/counter-todo/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.App {
text-align: center;
}

.App-logo {
height: 40vmin;
pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-float infinite 3s ease-in-out;
}
}

.App-header {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
}

.App-link {
color: rgb(112, 76, 182);
}

@keyframes App-logo-float {
0% {
transform: translateY(0);
}
50% {
transform: translateY(10px);
}
100% {
transform: translateY(0px);
}
}
122 changes: 122 additions & 0 deletions examples/lazy-injection/counter-todo/src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { screen, waitFor } from "@testing-library/react"
import App from "./App"
import { renderWithProviders } from "./utils/test-utils"
import userEvent from "@testing-library/user-event"

async function ensureCounterLoaded() {
await userEvent.click(screen.getByText("Counter example (lazy)"))

await waitFor(() => expect(screen.queryByTestId("count")).toBeInTheDocument())
}

test("App should have correct initial render", async () => {
renderWithProviders(<App />)

// The app should be rendered correctly
expect(screen.getByText(/learn/i)).toBeInTheDocument()

await ensureCounterLoaded()

// Initial state: count should be 0, incrementValue should be 2
expect(screen.getByTestId("count")).toHaveTextContent("0")
expect(screen.getByLabelText("Set increment amount")).toHaveValue(2)
})

test("Increment value and Decrement value should work as expected", async () => {
const { user } = renderWithProviders(<App />)

await ensureCounterLoaded()

// Click on "+" => Count should be 1
await user.click(screen.getByLabelText("Increment value"))
expect(screen.getByTestId("count")).toHaveTextContent("1")

// Click on "-" => Count should be 0
await user.click(screen.getByLabelText("Decrement value"))
expect(screen.getByTestId("count")).toHaveTextContent("0")
})

test("Add Amount should work as expected", async () => {
const { user } = renderWithProviders(<App />)

await ensureCounterLoaded()

// "Add Amount" button is clicked => Count should be 2
await user.click(screen.getByText("Add Amount"))
expect(screen.getByTestId("count")).toHaveTextContent("2")

const incrementValueInput = screen.getByLabelText("Set increment amount")
// incrementValue is 2, click on "Add Amount" => Count should be 4
await user.clear(incrementValueInput)
await user.type(incrementValueInput, "2")
await user.click(screen.getByText("Add Amount"))
expect(screen.getByTestId("count")).toHaveTextContent("4")

// [Negative number] incrementValue is -1, click on "Add Amount" => Count should be 3
await user.clear(incrementValueInput)
await user.type(incrementValueInput, "-1")
await user.click(screen.getByText("Add Amount"))
expect(screen.getByTestId("count")).toHaveTextContent("3")
})

it("Add Async should work as expected", async () => {
const { user } = renderWithProviders(<App />)

await ensureCounterLoaded()

// "Add Async" button is clicked => Count should be 2
await user.click(screen.getByText("Add Async"))

await waitFor(() =>
expect(screen.getByTestId("count")).toHaveTextContent("2"),
)

const incrementValueInput = screen.getByLabelText("Set increment amount")
// incrementValue is 2, click on "Add Async" => Count should be 4
await user.clear(incrementValueInput)
await user.type(incrementValueInput, "2")

await user.click(screen.getByText("Add Async"))
await waitFor(() =>
expect(screen.getByTestId("count")).toHaveTextContent("4"),
)

// [Negative number] incrementValue is -1, click on "Add Async" => Count should be 3
await user.clear(incrementValueInput)
await user.type(incrementValueInput, "-1")
await user.click(screen.getByText("Add Async"))
await waitFor(() =>
expect(screen.getByTestId("count")).toHaveTextContent("3"),
)
})

test("Add If Odd should work as expected", async () => {
const { user } = renderWithProviders(<App />)

await ensureCounterLoaded()

// "Add If Odd" button is clicked => Count should stay 0
await user.click(screen.getByText("Add If Odd"))
expect(screen.getByTestId("count")).toHaveTextContent("0")

// Click on "+" => Count should be updated to 1
await user.click(screen.getByLabelText("Increment value"))
expect(screen.getByTestId("count")).toHaveTextContent("1")

// "Add If Odd" button is clicked => Count should be updated to 3
await user.click(screen.getByText("Add If Odd"))
expect(screen.getByTestId("count")).toHaveTextContent("3")

const incrementValueInput = screen.getByLabelText("Set increment amount")
// incrementValue is 1, click on "Add If Odd" => Count should be updated to 4
await user.clear(incrementValueInput)
await user.type(incrementValueInput, "1")
await user.click(screen.getByText("Add If Odd"))
expect(screen.getByTestId("count")).toHaveTextContent("4")

// click on "Add If Odd" => Count should stay 4
await user.clear(incrementValueInput)
await user.type(incrementValueInput, "-1")
await user.click(screen.getByText("Add If Odd"))
expect(screen.getByTestId("count")).toHaveTextContent("4")
})
Loading
Loading