This commit is contained in:
e560248
2025-04-08 14:05:32 +02:00
parent 88de79086e
commit d5c52968a6
8 changed files with 153 additions and 6 deletions

View File

@@ -3,10 +3,10 @@
* @type {import("prettier").Config} * @type {import("prettier").Config}
*/ */
const config = { const config = {
trailingComma: "es5", trailingComma: 'es5',
tabWidth: 2, tabWidth: 2,
semi: false, semi: true,
singleQuote: true, singleQuote: true,
}; }
export default config; export default config

View File

@@ -9,6 +9,8 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"immer": "^10.1.1", "immer": "^10.1.1",
"mobx": "^6.13.7",
"mobx-react-lite": "^4.1.0",
"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",
@@ -3949,6 +3951,41 @@
"node": ">=16 || 14 >=14.17" "node": ">=16 || 14 >=14.17"
} }
}, },
"node_modules/mobx": {
"version": "6.13.7",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/mobx/-/mobx-6.13.7.tgz",
"integrity": "sha512-aChaVU/DO5aRPmk1GX8L+whocagUUpBQqoPtJk+cm7UOXUk87J4PeWCh6nNmTTIfEhiR9DI/+FnA8dln/hTK7g==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mobx"
}
},
"node_modules/mobx-react-lite": {
"version": "4.1.0",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/mobx-react-lite/-/mobx-react-lite-4.1.0.tgz",
"integrity": "sha512-QEP10dpHHBeQNv1pks3WnHRCem2Zp636lq54M2nKO2Sarr13pL4u6diQXf65yzXUn0mkk18SyIDCm9UOJYTi1w==",
"license": "MIT",
"dependencies": {
"use-sync-external-store": "^1.4.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mobx"
},
"peerDependencies": {
"mobx": "^6.9.0",
"react": "^16.8.0 || ^17 || ^18 || ^19"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/mri": { "node_modules/mri": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/mri/-/mri-1.2.0.tgz", "resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/mri/-/mri-1.2.0.tgz",
@@ -5650,6 +5687,15 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/use-sync-external-store": {
"version": "1.5.0",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
"license": "MIT",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "6.2.5", "version": "6.2.5",
"resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/vite/-/vite-6.2.5.tgz", "resolved": "https://bin.sbb.ch/artifactory/api/npm/npm/vite/-/vite-6.2.5.tgz",

View File

@@ -18,6 +18,8 @@
}, },
"dependencies": { "dependencies": {
"immer": "^10.1.1", "immer": "^10.1.1",
"mobx": "^6.13.7",
"mobx-react-lite": "^4.1.0",
"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

@@ -12,6 +12,7 @@ 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' import ImmerPage from './pages/ImmerPage'
import MobXPage from './pages/MobXPage'
function App() { function App() {
return ( return (
@@ -27,6 +28,7 @@ function App() {
<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 />} /> <Route path="/immer" element={<ImmerPage />} />
<Route path="/mobx" element={<MobXPage />} />
</Routes> </Routes>
</MainLayout> </MainLayout>
) )

View File

@@ -1,6 +1,8 @@
import './Navigation.css'
export default function Navigation() { export default function Navigation() {
return ( return (
<nav> <nav className="navigation">
<ul> <ul>
<li> <li>
<a href="/">Home</a> <a href="/">Home</a>
@@ -24,7 +26,10 @@ export default function Navigation() {
<a href="/modalpage">Modal</a> <a href="/modalpage">Modal</a>
</li> </li>
<li> <li>
<a href="/zustandcounterpage">ZustandCounterPage</a> <a href="/zustandcounterpage">Store: Zustand</a>
</li>
<li>
<a href="/mobx">Store: MobX</a>
</li> </li>
<li> <li>
<a href="/hoc">HOC</a> <a href="/hoc">HOC</a>

View File

@@ -0,0 +1,28 @@
.navigation {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background-color: #282c34;
}
.navigation a {
color: white;
text-decoration: none;
padding: 10px;
}
.navigation a:hover {
background-color: #057e9f;
border-radius: 5px;
transition: background-color 0.3s ease;
text-decoration: none;
}
.navigation ul {
list-style: none;
display: flex;
gap: 20px;
flex-wrap: wrap;
align-items: center;
}
.navigation ul li {
display: inline;
}

View File

@@ -0,0 +1,29 @@
import { makeAutoObservable } from 'mobx'
class CounterStore {
count = 0
message = 'Hello, MobX!'
constructor() {
makeAutoObservable(this)
}
increment() {
this.count++
}
decrement() {
this.count--
}
reset() {
this.count = 0
}
updateMessage(newMessage: string) {
this.message = newMessage
}
}
const counterStore = new CounterStore()
export default counterStore

View File

@@ -0,0 +1,35 @@
import { observer } from 'mobx-react-lite'
import ComponentWrapper from '../common/components/ComponentWrapper/ComponentWrapper'
import counterStore from '../common/stores/mobx-store'
const MobXPage = observer(() => {
return (
<ComponentWrapper title="MobX">
<div>
<h3>Counter: {counterStore.count}</h3>
<button onClick={() => counterStore.increment()}>Increment</button>
<button onClick={() => counterStore.decrement()}>Decrement</button>
</div>
<div>
<h3>Message: {counterStore.message}</h3>
<MessageUpdater />
<button onClick={() => counterStore.reset()}>Reset</button>
</div>
</ComponentWrapper>
)
})
export default MobXPage
function MessageUpdater() {
return (
<div>
<h3>Update Message</h3>
<input
type="text"
value={counterStore.message}
onChange={(e) => counterStore.updateMessage(e.target.value)}
/>
</div>
)
}