feat: Add Counter component with reducers
This commit is contained in:
parent
82b898e9eb
commit
79195a1892
@ -47,6 +47,7 @@ Comme expliqué plus tôt, un reducer est une fonction qui prend en paramètre u
|
|||||||
Parlons dans un premier temps de la signature d'un reducer :
|
Parlons dans un premier temps de la signature d'un reducer :
|
||||||
|
|
||||||
{% tabs defaultSelectedTab="jsx" %}
|
{% tabs defaultSelectedTab="jsx" %}
|
||||||
|
|
||||||
{% tab value="jsx" label="JSX" %}
|
{% tab value="jsx" label="JSX" %}
|
||||||
{% snippet path="react/reducer/reducer-example.jsx" language="jsx" showLineNumbers=true /%}
|
{% snippet path="react/reducer/reducer-example.jsx" language="jsx" showLineNumbers=true /%}
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
@ -54,6 +55,7 @@ Parlons dans un premier temps de la signature d'un reducer :
|
|||||||
{% tab value="tsx" label="TSX" %}
|
{% tab value="tsx" label="TSX" %}
|
||||||
{% snippet path="react/reducer/reducer-example.tsx" language="tsx" showLineNumbers=true /%}
|
{% snippet path="react/reducer/reducer-example.tsx" language="tsx" showLineNumbers=true /%}
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
|
|
||||||
Comme tu peux le voir, on récupère bien deux paramètres : `state` et `action`.
|
Comme tu peux le voir, on récupère bien deux paramètres : `state` et `action`.
|
||||||
@ -95,16 +97,13 @@ import { useReducer } from "react";
|
|||||||
Ensuite, on va définir notre état initial :
|
Ensuite, on va définir notre état initial :
|
||||||
|
|
||||||
{% tabs defaultSelectedTab="js" %}
|
{% tabs defaultSelectedTab="js" %}
|
||||||
|
|
||||||
{% tab value="js" label="JavaScript" %}
|
{% tab value="js" label="JavaScript" %}
|
||||||
|
|
||||||
{% snippet path="react/reducer/reducer-initial-state.js" language="js" /%}
|
{% snippet path="react/reducer/reducer-initial-state.js" language="js" /%}
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="ts" label="TypeScript" %}
|
{% tab value="ts" label="TypeScript" %}
|
||||||
|
|
||||||
{% snippet path="react/reducer/reducer-initial-state.ts" language="ts" /%}
|
{% snippet path="react/reducer/reducer-initial-state.ts" language="ts" /%}
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
@ -114,15 +113,11 @@ On peut maintenant définir notre reducer :
|
|||||||
{% tabs defaultSelectedTab="js" %}
|
{% tabs defaultSelectedTab="js" %}
|
||||||
|
|
||||||
{% tab value="js" label="JavaScript" %}
|
{% tab value="js" label="JavaScript" %}
|
||||||
|
|
||||||
{% snippet path="react/reducer/reducer.js" language="js" showLineNumbers=true /%}
|
{% snippet path="react/reducer/reducer.js" language="js" showLineNumbers=true /%}
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="ts" label="TypeScript" %}
|
{% tab value="ts" label="TypeScript" %}
|
||||||
|
|
||||||
{% snippet path="react/reducer/reducer.ts" language="ts" showLineNumbers=true /%}
|
{% snippet path="react/reducer/reducer.ts" language="ts" showLineNumbers=true /%}
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
@ -143,15 +138,11 @@ Enfin, on peut utiliser le hook useReducer dans notre composant :
|
|||||||
{% tabs defaultSelectedTab="js" %}
|
{% tabs defaultSelectedTab="js" %}
|
||||||
|
|
||||||
{% tab value="js" label="JavaScript" %}
|
{% tab value="js" label="JavaScript" %}
|
||||||
|
|
||||||
{% snippet path="react/reducer/reducer-hook.js" language="js" /%}
|
{% snippet path="react/reducer/reducer-hook.js" language="js" /%}
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="ts" label="TypeScript" %}
|
{% tab value="ts" label="TypeScript" %}
|
||||||
|
|
||||||
{% snippet path="react/reducer/reducer-hook.ts" language="ts" /%}
|
{% snippet path="react/reducer/reducer-hook.ts" language="ts" /%}
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
@ -160,9 +151,7 @@ Enfin, on peut utiliser le hook useReducer dans notre composant :
|
|||||||
|
|
||||||
Pour modifier l'état, on va donc appeler `dispatch` avec une action :
|
Pour modifier l'état, on va donc appeler `dispatch` avec une action :
|
||||||
|
|
||||||
```js
|
{% snippet path="react/reducer/reducer-dispatch-increment.js" language="js" /%}
|
||||||
dispatch({ type: "INCREMENT" });
|
|
||||||
```
|
|
||||||
|
|
||||||
Et voilà, tu sais maintenant comment utiliser `useReducer` dans une application React ! 🎉
|
Et voilà, tu sais maintenant comment utiliser `useReducer` dans une application React ! 🎉
|
||||||
|
|
||||||
@ -186,12 +175,7 @@ Pour contrer ces problèmes, on va créer des actions et des types d'actions pou
|
|||||||
|
|
||||||
Nos types d'actions seront tous des chaînes de caractères. On va donc pouvoir les définir sous forme de constantes.
|
Nos types d'actions seront tous des chaînes de caractères. On va donc pouvoir les définir sous forme de constantes.
|
||||||
|
|
||||||
```js
|
{% snippet path="react/reducer/reducer-actions-constants.js" language="js" /%}
|
||||||
export const INCREMENT = "INCREMENT";
|
|
||||||
export const DECREMENT = "DECREMENT";
|
|
||||||
export const RESET = "RESET";
|
|
||||||
export const SET = "SET";
|
|
||||||
```
|
|
||||||
|
|
||||||
{% callout type="note" title="Regrouper les exports" %}
|
{% callout type="note" title="Regrouper les exports" %}
|
||||||
|
|
||||||
@ -202,29 +186,11 @@ Bien vu ! Et pour TypeScript, on peut aller encore plus loin en créant un `enum
|
|||||||
{% tabs defaultSelectedTab="js" %}
|
{% tabs defaultSelectedTab="js" %}
|
||||||
|
|
||||||
{% tab value="js" label="JavaScript" %}
|
{% tab value="js" label="JavaScript" %}
|
||||||
|
{% snippet path="react/reducer/reducer-actions-enum.js" language="js" /%}
|
||||||
```js
|
|
||||||
export const CounterActionTypes = {
|
|
||||||
INCREMENT: "INCREMENT",
|
|
||||||
DECREMENT: "DECREMENT",
|
|
||||||
RESET: "RESET",
|
|
||||||
SET: "SET",
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="ts" label="TypeScript" %}
|
{% tab value="ts" label="TypeScript" %}
|
||||||
|
{% snippet path="react/reducer/reducer-actions-enum.ts" language="ts" /%}
|
||||||
```ts
|
|
||||||
export const enum CounterActionTypes {
|
|
||||||
INCREMENT = "INCREMENT",
|
|
||||||
DECREMENT = "DECREMENT",
|
|
||||||
RESET = "RESET",
|
|
||||||
SET = "SET",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
@ -237,32 +203,11 @@ Si tu utilises JavaScript, je suis désolé de te dire que tu ne peux pas **fort
|
|||||||
|
|
||||||
En revanche, si tu utilises TypeScript, tu peux définir les actions de la manière suivante :
|
En revanche, si tu utilises TypeScript, tu peux définir les actions de la manière suivante :
|
||||||
|
|
||||||
```ts
|
{% snippet path="react/reducer/reducer-actions-union.ts" language="ts" /%}
|
||||||
export type CounterAction =
|
|
||||||
| { type: CounterActionTypes.INCREMENT }
|
|
||||||
| { type: CounterActionTypes.DECREMENT }
|
|
||||||
| { type: CounterActionTypes.RESET }
|
|
||||||
| { type: CounterActionTypes.SET; payload: number };
|
|
||||||
```
|
|
||||||
|
|
||||||
Tu pourras alors utiliser `CounterAction` pour typer les actions de ton reducer :
|
Tu pourras alors utiliser `CounterAction` pour typer les actions de ton reducer :
|
||||||
|
|
||||||
```ts
|
{% snippet path="react/reducer/reducer-actions-union-use.ts" language="ts" /%}
|
||||||
const reducer = (state: State, action: CounterAction) => {
|
|
||||||
switch (action.type) {
|
|
||||||
case CounterActionTypes.INCREMENT:
|
|
||||||
return { ...state, count: state.count + 1 };
|
|
||||||
case CounterActionTypes.DECREMENT:
|
|
||||||
return { ...state, count: state.count - 1 };
|
|
||||||
case CounterActionTypes.RESET:
|
|
||||||
return { ...state, count: 0 };
|
|
||||||
case CounterActionTypes.SET:
|
|
||||||
return { ...state, count: action.payload };
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### Action creators
|
### Action creators
|
||||||
|
|
||||||
@ -271,195 +216,48 @@ Pour éviter de se tromper dans le type de l'action, on peut se créer des fonct
|
|||||||
{% tabs defaultSelectedTab="js" %}
|
{% tabs defaultSelectedTab="js" %}
|
||||||
|
|
||||||
{% tab value="js" label="JavaScript" %}
|
{% tab value="js" label="JavaScript" %}
|
||||||
|
{% snippet path="react/reducer/reducer-action-creator.js" language="js" /%}
|
||||||
```js
|
|
||||||
export const actions = {
|
|
||||||
increment: () => ({ type: CounterActionTypes.INCREMENT }),
|
|
||||||
decrement: () => ({ type: CounterActionTypes.DECREMENT }),
|
|
||||||
reset: () => ({ type: CounterActionTypes.RESET }),
|
|
||||||
set: (value) => ({ type: CounterActionTypes.SET, payload: value }),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="ts" label="TypeScript" %}
|
{% tab value="ts" label="TypeScript" %}
|
||||||
|
{% snippet path="react/reducer/reducer-action-creator.ts" language="ts" /%}
|
||||||
```ts
|
|
||||||
export const actions = {
|
|
||||||
increment: (): CounterAction => ({ type: CounterActionTypes.INCREMENT }),
|
|
||||||
decrement: (): CounterAction => ({ type: CounterActionTypes.DECREMENT }),
|
|
||||||
reset: (): CounterAction => ({ type: CounterActionTypes.RESET }),
|
|
||||||
set: (value: number): CounterAction => ({ type: CounterActionTypes.SET, payload: value }),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
|
|
||||||
Maintenant le dispatch de nos actions sera beaucoup plus simple et éviter davantage les erreurs lors du développement !
|
Maintenant le dispatch de nos actions sera beaucoup plus simple et éviter davantage les erreurs lors du développement !
|
||||||
|
|
||||||
```js
|
{% snippet path="react/reducer/reducer-dispatch-action-creator.js" language="js" /%}
|
||||||
dispatch(actions.increment());
|
|
||||||
dispatch(actions.set(10));
|
|
||||||
```
|
|
||||||
|
|
||||||
## Les fichiers complets
|
## Les fichiers complets
|
||||||
|
|
||||||
On a vu beaucoup de chose et les fichiers sont un peu éparpillés.
|
On a vu beaucoup de chose et les fichiers sont un peu éparpillés.
|
||||||
Pour t'aider à mieux comprendre le fonctionnement du hook `useReducer` et comment l'implementer, voici les fichiers complets :
|
Pour t'aider à mieux comprendre le fonctionnement du hook `useReducer` et comment l'implementer, voici les fichiers complets :
|
||||||
|
|
||||||
### Fichier `counterReducer.js` ou `counterReducer.ts`
|
### Fichier counterReducer.js ou counterReducer.ts
|
||||||
|
|
||||||
{% tabs defaultSelectedTab="js" %}
|
{% tabs defaultSelectedTab="js" %}
|
||||||
|
|
||||||
{% tab value="js" label="JavaScript" %}
|
{% tab value="js" label="JavaScript" %}
|
||||||
|
{% snippet path="react/reducer/file-counterReducer.js" language="js" showLineNumbers=true label="src/reducers/counterReducer.js" /%}
|
||||||
```js
|
|
||||||
const CounterActionTypes = {
|
|
||||||
INCREMENT: "INCREMENT",
|
|
||||||
DECREMENT: "DECREMENT",
|
|
||||||
RESET: "RESET",
|
|
||||||
SET: "SET",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const initialState = { count: 0 };
|
|
||||||
|
|
||||||
export const reducer = (state, action) => {
|
|
||||||
switch (action.type) {
|
|
||||||
case CounterActionTypes.INCREMENT:
|
|
||||||
return { ...state, count: state.count + 1 };
|
|
||||||
case CounterActionTypes.DECREMENT:
|
|
||||||
return { ...state, count: state.count - 1 };
|
|
||||||
case CounterActionTypes.RESET:
|
|
||||||
return { ...state, count: 0 };
|
|
||||||
case CounterActionTypes.SET:
|
|
||||||
return { ...state, count: action.payload };
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const actions = {
|
|
||||||
increment: () => ({ type: CounterActionTypes.INCREMENT }),
|
|
||||||
decrement: () => ({ type: CounterActionTypes.DECREMENT }),
|
|
||||||
reset: () => ({ type: CounterActionTypes.RESET }),
|
|
||||||
set: (value) => ({ type: CounterActionTypes.SET, payload: value }),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="ts" label="TypeScript" %}
|
{% tab value="ts" label="TypeScript" %}
|
||||||
|
{% snippet path="react/reducer/file-counterReducer.ts" language="ts" showLineNumbers=true label="src/reducers/counterReducer.ts" /%}
|
||||||
```ts
|
|
||||||
const enum CounterActionTypes {
|
|
||||||
INCREMENT = "INCREMENT",
|
|
||||||
DECREMENT = "DECREMENT",
|
|
||||||
RESET = "RESET",
|
|
||||||
SET = "SET",
|
|
||||||
}
|
|
||||||
|
|
||||||
type State = {
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Action =
|
|
||||||
| { type: CounterActionTypes.INCREMENT }
|
|
||||||
| { type: CounterActionTypes.DECREMENT }
|
|
||||||
| { type: CounterActionTypes.RESET }
|
|
||||||
| { type: CounterActionTypes.SET; payload: number };
|
|
||||||
|
|
||||||
export const initialState: State = { count: 0 };
|
|
||||||
|
|
||||||
export const reducer = (state: State, action: Action) => {
|
|
||||||
switch (action.type) {
|
|
||||||
case CounterActionTypes.INCREMENT:
|
|
||||||
return { ...state, count: state.count + 1 };
|
|
||||||
case CounterActionTypes.DECREMENT:
|
|
||||||
return { ...state, count: state.count - 1 };
|
|
||||||
case CounterActionTypes.RESET:
|
|
||||||
return { ...state, count: 0 };
|
|
||||||
case CounterActionTypes.SET:
|
|
||||||
return { ...state, count: action.payload };
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const actions = {
|
|
||||||
increment: (): Action => ({ type: CounterActionTypes.INCREMENT }),
|
|
||||||
decrement: (): Action => ({ type: CounterActionTypes.DECREMENT }),
|
|
||||||
reset: (): Action => ({ type: CounterActionTypes.RESET }),
|
|
||||||
set: (value: number): Action => ({ type: CounterActionTypes.SET, payload: value }),
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
|
|
||||||
### Fichier `Counter.jsx` ou `Counter.tsx`
|
### Fichier Counter.jsx ou Counter.tsx
|
||||||
|
|
||||||
{% tabs defaultSelectedTab="jsx" %}
|
{% tabs defaultSelectedTab="jsx" %}
|
||||||
|
|
||||||
{% tab value="jsx" label="JSX" %}
|
{% tab value="jsx" label="JSX" %}
|
||||||
|
{% snippet path="react/reducer/file-counter.jsx" language="jsx" showLineNumbers=true label="src/components/Counter.jsx" /%}
|
||||||
```jsx
|
|
||||||
import { initialState, actions, reducer } from "../reducers/counterReducer";
|
|
||||||
import { useReducer } from "react";
|
|
||||||
|
|
||||||
const Counter = () => {
|
|
||||||
const [state, dispatch] = useReducer(reducer, initialState);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<p>Count: {state.count}</p>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.increment())}>Increment</button>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.decrement())}>Decrement</button>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.reset())}>Reset</button>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.set(10))}>Set counter to 10</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Counter;
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% tab value="tsx" label="TSX" %}
|
{% tab value="tsx" label="TSX" %}
|
||||||
|
{% snippet path="react/reducer/file-counter.tsx" language="tsx" showLineNumbers=true label="src/components/Counter.tsx" /%}
|
||||||
```tsx
|
|
||||||
import { initialState, actions, reducer } from "../reducers/counterReducer";
|
|
||||||
import { useReducer } from "react";
|
|
||||||
|
|
||||||
const Counter = () => {
|
|
||||||
const [state, dispatch] = useReducer(reducer, initialState);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<p>Count: {state.count}</p>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.increment())}>Increment</button>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.decrement())}>Decrement</button>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.reset())}>Reset</button>
|
|
||||||
|
|
||||||
<button onClick={() => dispatch(actions.set(10))}>Set counter to 10</button>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Counter;
|
|
||||||
```
|
|
||||||
|
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
|
|||||||
22
app/data/snippets/react/reducer/file-counter.jsx
Normal file
22
app/data/snippets/react/reducer/file-counter.jsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { initialState, actions, reducer } from "../reducers/counterReducer";
|
||||||
|
import { useReducer } from "react";
|
||||||
|
|
||||||
|
const Counter = () => {
|
||||||
|
const [state, dispatch] = useReducer(reducer, initialState);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>Count: {state.count}</p>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.increment())}>Increment</button>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.decrement())}>Decrement</button>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.reset())}>Reset</button>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.set(10))}>Set counter to 10</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Counter;
|
||||||
22
app/data/snippets/react/reducer/file-counter.tsx
Normal file
22
app/data/snippets/react/reducer/file-counter.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { initialState, actions, reducer } from "../reducers/counterReducer";
|
||||||
|
import { useReducer } from "react";
|
||||||
|
|
||||||
|
const Counter = () => {
|
||||||
|
const [state, dispatch] = useReducer(reducer, initialState);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<p>Count: {state.count}</p>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.increment())}>Increment</button>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.decrement())}>Decrement</button>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.reset())}>Reset</button>
|
||||||
|
|
||||||
|
<button onClick={() => dispatch(actions.set(10))}>Set counter to 10</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Counter;
|
||||||
30
app/data/snippets/react/reducer/file-counterReducer.js
Normal file
30
app/data/snippets/react/reducer/file-counterReducer.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const CounterActionTypes = {
|
||||||
|
INCREMENT: "INCREMENT",
|
||||||
|
DECREMENT: "DECREMENT",
|
||||||
|
RESET: "RESET",
|
||||||
|
SET: "SET",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initialState = { count: 0 };
|
||||||
|
|
||||||
|
export const reducer = (state, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case CounterActionTypes.INCREMENT:
|
||||||
|
return { ...state, count: state.count + 1 };
|
||||||
|
case CounterActionTypes.DECREMENT:
|
||||||
|
return { ...state, count: state.count - 1 };
|
||||||
|
case CounterActionTypes.RESET:
|
||||||
|
return { ...state, count: 0 };
|
||||||
|
case CounterActionTypes.SET:
|
||||||
|
return { ...state, count: action.payload };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
increment: () => ({ type: CounterActionTypes.INCREMENT }),
|
||||||
|
decrement: () => ({ type: CounterActionTypes.DECREMENT }),
|
||||||
|
reset: () => ({ type: CounterActionTypes.RESET }),
|
||||||
|
set: (value) => ({ type: CounterActionTypes.SET, payload: value }),
|
||||||
|
};
|
||||||
40
app/data/snippets/react/reducer/file-counterReducer.ts
Normal file
40
app/data/snippets/react/reducer/file-counterReducer.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const enum CounterActionTypes {
|
||||||
|
INCREMENT = "INCREMENT",
|
||||||
|
DECREMENT = "DECREMENT",
|
||||||
|
RESET = "RESET",
|
||||||
|
SET = "SET",
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
count: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Action =
|
||||||
|
| { type: CounterActionTypes.INCREMENT }
|
||||||
|
| { type: CounterActionTypes.DECREMENT }
|
||||||
|
| { type: CounterActionTypes.RESET }
|
||||||
|
| { type: CounterActionTypes.SET; payload: number };
|
||||||
|
|
||||||
|
export const initialState: State = { count: 0 };
|
||||||
|
|
||||||
|
export const reducer = (state: State, action: Action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case CounterActionTypes.INCREMENT:
|
||||||
|
return { ...state, count: state.count + 1 };
|
||||||
|
case CounterActionTypes.DECREMENT:
|
||||||
|
return { ...state, count: state.count - 1 };
|
||||||
|
case CounterActionTypes.RESET:
|
||||||
|
return { ...state, count: 0 };
|
||||||
|
case CounterActionTypes.SET:
|
||||||
|
return { ...state, count: action.payload };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions = {
|
||||||
|
increment: (): Action => ({ type: CounterActionTypes.INCREMENT }),
|
||||||
|
decrement: (): Action => ({ type: CounterActionTypes.DECREMENT }),
|
||||||
|
reset: (): Action => ({ type: CounterActionTypes.RESET }),
|
||||||
|
set: (value: number): Action => ({ type: CounterActionTypes.SET, payload: value }),
|
||||||
|
};
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
export const actions = {
|
||||||
|
increment: () => ({ type: CounterActionTypes.INCREMENT }),
|
||||||
|
decrement: () => ({ type: CounterActionTypes.DECREMENT }),
|
||||||
|
reset: () => ({ type: CounterActionTypes.RESET }),
|
||||||
|
set: (value) => ({ type: CounterActionTypes.SET, payload: value }),
|
||||||
|
};
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
export const actions = {
|
||||||
|
increment: (): CounterAction => ({ type: CounterActionTypes.INCREMENT }),
|
||||||
|
decrement: (): CounterAction => ({ type: CounterActionTypes.DECREMENT }),
|
||||||
|
reset: (): CounterAction => ({ type: CounterActionTypes.RESET }),
|
||||||
|
set: (value: number): CounterAction => ({ type: CounterActionTypes.SET, payload: value }),
|
||||||
|
};
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
export const INCREMENT = "INCREMENT";
|
||||||
|
export const DECREMENT = "DECREMENT";
|
||||||
|
export const RESET = "RESET";
|
||||||
|
export const SET = "SET";
|
||||||
6
app/data/snippets/react/reducer/reducer-actions-enum.js
Normal file
6
app/data/snippets/react/reducer/reducer-actions-enum.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export const CounterActionTypes = {
|
||||||
|
INCREMENT: "INCREMENT",
|
||||||
|
DECREMENT: "DECREMENT",
|
||||||
|
RESET: "RESET",
|
||||||
|
SET: "SET",
|
||||||
|
};
|
||||||
6
app/data/snippets/react/reducer/reducer-actions-enum.ts
Normal file
6
app/data/snippets/react/reducer/reducer-actions-enum.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export const enum CounterActionTypes {
|
||||||
|
INCREMENT = "INCREMENT",
|
||||||
|
DECREMENT = "DECREMENT",
|
||||||
|
RESET = "RESET",
|
||||||
|
SET = "SET",
|
||||||
|
}
|
||||||
14
app/data/snippets/react/reducer/reducer-actions-union-use.ts
Normal file
14
app/data/snippets/react/reducer/reducer-actions-union-use.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const reducer = (state: State, action: CounterAction) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case CounterActionTypes.INCREMENT:
|
||||||
|
return { ...state, count: state.count + 1 };
|
||||||
|
case CounterActionTypes.DECREMENT:
|
||||||
|
return { ...state, count: state.count - 1 };
|
||||||
|
case CounterActionTypes.RESET:
|
||||||
|
return { ...state, count: 0 };
|
||||||
|
case CounterActionTypes.SET:
|
||||||
|
return { ...state, count: action.payload };
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
6
app/data/snippets/react/reducer/reducer-actions-union.ts
Normal file
6
app/data/snippets/react/reducer/reducer-actions-union.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
export type CounterAction =
|
||||||
|
| { type: CounterActionTypes.INCREMENT }
|
||||||
|
| { type: CounterActionTypes.DECREMENT }
|
||||||
|
| { type: CounterActionTypes.RESET }
|
||||||
|
| { type: CounterActionTypes.SET; payload: number };
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
dispatch(actions.increment());
|
||||||
|
dispatch(actions.set(10));
|
||||||
@ -0,0 +1 @@
|
|||||||
|
dispatch({ type: "INCREMENT" });
|
||||||
Loading…
Reference in New Issue
Block a user