add immerJs example

This commit is contained in:
e560248
2025-04-08 13:28:46 +02:00
parent 6577698459
commit 88de79086e
8 changed files with 77 additions and 1 deletions

View File

@@ -8,6 +8,7 @@
"name": "react-advanced-tag1", "name": "react-advanced-tag1",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"immer": "^10.1.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-router-dom": "^7.5.0", "react-router-dom": "^7.5.0",
@@ -3465,6 +3466,16 @@
"node": ">= 4" "node": ">= 4"
} }
}, },
"node_modules/immer": {
"version": "10.1.1",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/immer/-/immer-10.1.1.tgz",
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
}
},
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.1", "version": "3.3.1",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/import-fresh/-/import-fresh-3.3.1.tgz", "resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/import-fresh/-/import-fresh-3.3.1.tgz",

View File

@@ -17,6 +17,7 @@
"prettier": "prettier ./src --write" "prettier": "prettier ./src --write"
}, },
"dependencies": { "dependencies": {
"immer": "^10.1.1",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-router-dom": "^7.5.0", "react-router-dom": "^7.5.0",

View File

@@ -11,6 +11,7 @@ import ComponentWrapperPage from './pages/ComponentWrapperPage'
import ZustandCounterPage from './pages/ZustandCounterPage' import ZustandCounterPage from './pages/ZustandCounterPage'
import ModalPage from './pages/ModalPage' import ModalPage from './pages/ModalPage'
import { HocPage } from './pages/HocPage' import { HocPage } from './pages/HocPage'
import ImmerPage from './pages/ImmerPage'
function App() { function App() {
return ( return (
@@ -25,6 +26,7 @@ function App() {
<Route path="/modalpage" element={<ModalPage />} /> <Route path="/modalpage" element={<ModalPage />} />
<Route path="/zustandcounterpage" element={<ZustandCounterPage />} /> <Route path="/zustandcounterpage" element={<ZustandCounterPage />} />
<Route path="/hoc" element={<HocPage />} /> <Route path="/hoc" element={<HocPage />} />
<Route path="/immer" element={<ImmerPage />} />
</Routes> </Routes>
</MainLayout> </MainLayout>
) )

View File

@@ -29,6 +29,9 @@ export default function Navigation() {
<li> <li>
<a href="/hoc">HOC</a> <a href="/hoc">HOC</a>
</li> </li>
<li>
<a href="/immer">Immer</a>
</li>
</ul> </ul>
</nav> </nav>
) )

View File

@@ -0,0 +1,44 @@
import { produce } from 'immer'
import { useState } from 'react'
export default function ImmerExercise() {
const [user, setUser] = useState({
name: 'Alice',
address: {
city: 'Wonderland',
zip: '12345',
},
})
const updateUser = () => {
// this is "normal" way to update state in objects
setUser((prevUser) => ({
...prevUser,
address: {
...prevUser.address,
city: 'New Wonderland',
},
}))
}
const updateUserWithImmer = () => {
// immer way
setUser((prevUser) =>
produce(prevUser, (draft) => {
draft.address.city = 'New Wonderland'
})
)
}
return (
<>
<p>
{user.address.city}: {user.name}
</p>
<button onClick={updateUser}>Update User</button>
<button onClick={updateUserWithImmer}>Update User with immerJs</button>
</>
)
}

View File

@@ -44,9 +44,11 @@ export default function RefExercise(): React.ReactElement {
} }
const handleChangeSubmit = () => { const handleChangeSubmit = () => {
// This is a bad way to handle form submission
const strasse = document.querySelector( const strasse = document.querySelector(
'input[name="strasse"]' 'input[name="strasse"]'
) as HTMLInputElement ) as HTMLInputElement
// This is a bad way to handle form submission
const city = document.querySelector( const city = document.querySelector(
'input[name="city"]' 'input[name="city"]'
) as HTMLInputElement ) as HTMLInputElement

View File

@@ -3,6 +3,9 @@ import { createRoot } from 'react-dom/client'
import './index.css' import './index.css'
import App from './App.tsx' import App from './App.tsx'
import { BrowserRouter } from 'react-router-dom' import { BrowserRouter } from 'react-router-dom'
import { enableMapSet } from 'immer'
enableMapSet()
createRoot(document.getElementById('root')!).render( createRoot(document.getElementById('root')!).render(
<StrictMode> <StrictMode>

View File

@@ -0,0 +1,10 @@
import ComponentWrapper from '../common/components/ComponentWrapper/ComponentWrapper'
import ImmerExercise from '../common/components/exercises/ImmerExercise'
export default function ImmerPage() {
return (
<ComponentWrapper title="Immer">
<ImmerExercise />
</ComponentWrapper>
)
}