Skip to content

Commit cb2818d

Browse files
committed
feat(recipes): add recipe for "using simplux in my React application"
1 parent 00bcc02 commit cb2818d

7 files changed

Lines changed: 239 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Here are some recipes that will show you how **simplux** can make life simple fo
3939

4040
### React
4141

42-
- [using **simplux** in my React application](recipes/react/using-in-react-application#readme) (work-in-progress)
42+
- [using **simplux** in my React application](recipes/react/using-in-react-application#readme)
4343
- [testing my components that read and change state](recipes/react/testing-components-using-state#readme) (work-in-progress)
4444
- [testing my components that trigger async work](recipes/react/testing-components-using-async#readme) (work-in-progress)
4545
- [using **simplux** with React Redux](recipes/react/using-with-react-redux#readme) (work-in-progress)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SKIP_PREFLIGHT_CHECK=true

recipes/react/using-in-react-application/README.md

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,82 @@ If you are new to **simplux** there is [a recipe](../../basics/getting-started#r
66

77
> You can play with the code for this recipe in this [code sandbox](https://codesandbox.io/s/github/MrWolfZ/simplux/tree/master/recipes/react/using-in-react-application).
88
9-
This recipe is still a work-in-progress.
9+
Before we start let's install all the packages we need (we assume you already have all packages required for React installed).
10+
11+
```sh
12+
npm i @simplux/core @simplux/immer @simplux/react @simplux/selectors redux -S
13+
```
14+
15+
We also register all extension packages.
16+
17+
```ts
18+
import '@simplux/immer'
19+
import '@simplux/react'
20+
import '@simplux/selectors'
21+
```
22+
23+
Now we're ready to go.
24+
25+
In this recipe we are going to build a simple counter component. Let's start by creating our module with some simple mutations and selectors. The React extension package adds a new `react` property to our modules that provides us a with a React hook called `useSelector` for using a module's state in a component.
26+
27+
```ts
28+
const {
29+
createMutations,
30+
createSelectors,
31+
32+
// the simplux react extension adds a hook for using the module's
33+
// state in a component
34+
react: {
35+
hooks: { useSelector },
36+
},
37+
} = createSimpluxModule({
38+
name: 'counter',
39+
initialState: {
40+
value: 0,
41+
},
42+
})
43+
44+
const { increment, incrementBy } = createMutations({
45+
increment(state) {
46+
state.value += 1
47+
},
48+
49+
incrementBy(state, amount: number) {
50+
state.value += amount
51+
},
52+
})
53+
54+
const { selectCounterValue } = createSelectors({
55+
selectCounterValue: ({ value }) => value,
56+
})
57+
```
58+
59+
Now we can start using this module in our counter component. As the name suggests the `useSelector` hook allows us to use our module's selectors inside our component. This hook also ensures that the component is updated whenever the selected value changes.
60+
61+
```tsx
62+
const Counter = () => {
63+
const value = useSelector(selectCounterValue)
64+
65+
// we can also use an inline selector
66+
const valueTimesTwo = useSelector(s => s.value * 2)
67+
68+
return (
69+
<>
70+
value: {value}
71+
<br />
72+
value * 2: {valueTimesTwo}
73+
<br />
74+
{/* we can use mutations directly as event handlers */}
75+
<button onClick={increment}>Increment</button>
76+
{/* we can also use mutations with arguments */}
77+
<button onClick={() => incrementBy(5)}>Increment by 5</button>
78+
</>
79+
)
80+
}
81+
```
82+
83+
And that is all you need to use **simplux** in your React application.
84+
85+
If your application also uses Redux we recommend you take a look at [our recipe](../../advanced/using-in-redux-application#readme) for using **simplux** with a custom Redux store.
86+
87+
We also encourage you to learn about [how to test](../testing-components-using-state#readme) the component that we have just created.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"name": "@simplux/recipes.advanced.using-in-react-application",
3+
"version": "0.3.0",
4+
"description": "This recipe shows you how simple it is to integrate simplux into your React application",
5+
"scripts": {
6+
"start": "react-scripts start"
7+
},
8+
"repository": {
9+
"type": "git",
10+
"url": "git+https://github.com/MrWolfZ/simplux.git"
11+
},
12+
"bugs": {
13+
"url": "https://github.com/MrWolfZ/simplux/issues"
14+
},
15+
"homepage": "https://github.com/MrWolfZ/simplux/tree/master/recipes/advanced/using-in-react-application#readme",
16+
"keywords": [
17+
"recipe",
18+
"redux",
19+
"simplux",
20+
"typescript"
21+
],
22+
"author": "Jonathan Ziller <jonathan.ziller@gmail.com> (https://www.github.com/MrWolfZ)",
23+
"license": "MIT",
24+
"private": true,
25+
"dependencies": {
26+
"@simplux/core": "0.3.0",
27+
"@simplux/immer": "0.3.0",
28+
"@simplux/react": "0.3.0",
29+
"@simplux/selectors": "0.3.0",
30+
"immer": "^3.1.3",
31+
"react": "^16.8.0",
32+
"react-dom": "^16.8.0",
33+
"redux": "^4.0.1"
34+
},
35+
"devDependencies": {
36+
"@types/react": "^16.8.0",
37+
"@types/react-dom": "^16.8.0",
38+
"react-scripts": "^3.0.1",
39+
"typescript": "^3.5.1",
40+
"webpack": "4.29.6",
41+
"webpack-dev-server": "3.2.1"
42+
},
43+
"browserslist": {
44+
"production": [
45+
">0.2%",
46+
"not dead",
47+
"not op_mini all"
48+
],
49+
"development": [
50+
"last 1 chrome version",
51+
"last 1 firefox version",
52+
"last 1 safari version"
53+
]
54+
}
55+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html lang="">
3+
<head>
4+
<meta charset="UTF-8" />
5+
</head>
6+
<body>
7+
<div id="root"></div>
8+
</body>
9+
</html>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// this code is part of the simplux recipe "using simplux in my React application":
2+
// https://github.com/MrWolfZ/simplux/tree/master/recipes/advanced/using-in-react-application
3+
4+
import { createSimpluxModule } from '@simplux/core'
5+
// we import all the simplux extension packages we are going to use
6+
import '@simplux/immer'
7+
import '@simplux/react'
8+
import '@simplux/selectors'
9+
import React from 'react'
10+
import { render } from 'react-dom'
11+
12+
// let's create a simple counter module
13+
14+
const {
15+
createMutations,
16+
createSelectors,
17+
18+
// the simplux react extension adds a hook for using the module's
19+
// state in a component
20+
react: {
21+
hooks: { useSelector },
22+
},
23+
} = createSimpluxModule({
24+
name: 'counter',
25+
initialState: {
26+
value: 0,
27+
},
28+
})
29+
30+
const { increment, incrementBy } = createMutations({
31+
increment(state) {
32+
state.value += 1
33+
},
34+
35+
incrementBy(state, amount: number) {
36+
state.value += amount
37+
},
38+
})
39+
40+
const { selectCounterValue } = createSelectors({
41+
selectCounterValue: ({ value }) => value,
42+
})
43+
44+
// now we can start using our module in our React components
45+
46+
const Counter = () => {
47+
// as the name suggests the useSelector hook allows us to use our
48+
// module's selectors inside our component; this hook ensures that
49+
// the component is updated whenever the selected value changes
50+
const value = useSelector(selectCounterValue)
51+
52+
// we can also use an inline selector
53+
const valueTimesTwo = useSelector(s => s.value * 2)
54+
55+
return (
56+
<>
57+
value: {value}
58+
<br />
59+
value * 2: {valueTimesTwo}
60+
<br />
61+
{/* we can use mutations directly as event handlers */}
62+
<button onClick={increment}>Increment</button>
63+
{/* we can also use mutations with arguments */}
64+
<button onClick={() => incrementBy(5)}>Increment by 5</button>
65+
</>
66+
)
67+
}
68+
69+
render(<Counter />, document.getElementById('root'))
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5",
4+
"lib": [
5+
"dom",
6+
"dom.iterable",
7+
"esnext"
8+
],
9+
"allowJs": true,
10+
"skipLibCheck": true,
11+
"esModuleInterop": true,
12+
"allowSyntheticDefaultImports": true,
13+
"strict": true,
14+
"forceConsistentCasingInFileNames": true,
15+
"module": "esnext",
16+
"moduleResolution": "node",
17+
"resolveJsonModule": true,
18+
"isolatedModules": true,
19+
"noEmit": true,
20+
"jsx": "preserve"
21+
},
22+
"include": [
23+
"src"
24+
]
25+
}

0 commit comments

Comments
 (0)