React+Redux: ajout slides Redux Saga
This commit is contained in:
parent
4aab1733df
commit
93f78ff5d5
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
|
@ -1,3 +1,8 @@
|
|||
---
|
||||
marp: true
|
||||
---
|
||||
|
||||
|
||||
<style>
|
||||
pre { font-size: 0.5em !important; }
|
||||
table { font-size: 0.6em !important; }
|
||||
|
@ -401,6 +406,8 @@ export default class Clock extends React.Component {
|
|||
|
||||
Les événements du DOM sont interceptés par le passage de "callbacks" sur les propriétés `on<Event>` des composants.
|
||||
|
||||
---
|
||||
|
||||
```jsx
|
||||
// my-app/src/components/counter.js
|
||||
|
||||
|
@ -531,8 +538,8 @@ https://reactjs.org/docs/react-component.html
|
|||
|
||||
### Séquence de montage
|
||||
|
||||
1. `constructor(props)`
|
||||
2. `componentWillMount()`
|
||||
1. `constructor(nextProps, currentState)`
|
||||
2. `static getDerivedStateFromProps(nextProps, currentState)`
|
||||
3. `render()`
|
||||
4. `componentDidMount()`
|
||||
|
||||
|
@ -540,11 +547,11 @@ https://reactjs.org/docs/react-component.html
|
|||
|
||||
### Séquence de mise à jour
|
||||
|
||||
1. `componentWillReceiveProps(nextProps)`
|
||||
1. `static getDerivedStateFromProps(nextProps, currentState)`
|
||||
2. `shouldComponentUpdate(nextProps, nextState)`
|
||||
3. `componentWillUpdate(nextProps, nextState)`
|
||||
4. `render()`
|
||||
5. `componentDidUpdate(prevProps, prevState)`
|
||||
3. `render()`
|
||||
4. `getSnapshotBeforeUpdate(prevProps, prevState)`
|
||||
5. `componentDidUpdate(prevProps, prevState, snapshot)`
|
||||
|
||||
---
|
||||
|
||||
|
@ -838,9 +845,9 @@ https://redux.js.org/
|
|||
|
||||
---
|
||||
|
||||
## Flot des données
|
||||
![bg right:75% contain](./img/redux_flow.png?1)
|
||||
|
||||
![center 100%](./img/redux_flow.png?1)
|
||||
## Flot des données
|
||||
|
||||
---
|
||||
|
||||
|
@ -905,7 +912,7 @@ export default const rootReducer = (state, action) => {
|
|||
---
|
||||
|
||||
## Création du `store`
|
||||
```
|
||||
```javascript
|
||||
// store.js
|
||||
|
||||
import { createStore } from 'redux'
|
||||
|
@ -921,9 +928,8 @@ export function configureStore(initialState = { products: [] }) {
|
|||
---
|
||||
## Tester
|
||||
|
||||
```
|
||||
```js
|
||||
// store.test.js
|
||||
|
||||
/* globals test, expect, jest */
|
||||
import { addProduct, removeProduct } from './actions'
|
||||
import { configureStore } from './store'
|
||||
|
@ -1099,6 +1105,146 @@ export default connect(mapStateToProps)(App)
|
|||
|
||||
---
|
||||
|
||||
## Redux-Saga
|
||||
|
||||
ou comment gérer les **"effets de bord"**
|
||||
|
||||
---
|
||||
|
||||
![bg right:75% contain](./img/reduxsaga_flow.png?1)
|
||||
|
||||
## Flot des données
|
||||
|
||||
---
|
||||
|
||||
### Cas d'usage
|
||||
|
||||
React-Redux permet d'intégrer au sein du "flux de travail" Redux la gestion des opérations asynchrones.
|
||||
|
||||
**Exemple** _Appels à des API distantes, opérations liées au passage du temps, messages websockets..._
|
||||
|
||||
Notamment, il offre une gestion de la **synchronisation d'opérations asynchrones** i.e. je dois attendre que l'opération A et l'opération B soient terminées pour effectuer l'opération C.
|
||||
|
||||
---
|
||||
|
||||
### Installation de la dépendance
|
||||
|
||||
```bash
|
||||
npm install --save redux-saga
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Ajout du middleware
|
||||
|
||||
```js
|
||||
// src/store/store.js
|
||||
import { createStore, applyMiddleware, combineReducers, compose } from 'redux'
|
||||
import myReducer from '../reducers/my'
|
||||
import rootSaga from '../sagas/root'
|
||||
import createSagaMiddleware from 'redux-saga'
|
||||
|
||||
const sagaMiddleware = createSagaMiddleware()
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
my: myReducer,
|
||||
});
|
||||
|
||||
export function configureStore(initialState = {}) {
|
||||
const store = createStore(
|
||||
rootReducer,
|
||||
initialState,
|
||||
compose(
|
||||
applyMiddleware(sagaMiddleware)
|
||||
)
|
||||
)
|
||||
sagaMiddleware.run(rootSaga);
|
||||
return store;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Création de la saga "racine"
|
||||
|
||||
_Avec une saga "factice" d'authentification_
|
||||
|
||||
```js
|
||||
// src/sagas/root.js
|
||||
import { all, takeLatest } from 'redux-saga/effects';
|
||||
import { LOGIN_REQUEST } from '../actions/auth';
|
||||
import { loginSaga } from './auth';
|
||||
|
||||
export default function* rootSaga() {
|
||||
yield all([
|
||||
takeLatest(LOGIN_REQUEST, loginSaga),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Définition des actions
|
||||
|
||||
```js
|
||||
// src/actions/auth.js
|
||||
export const LOGIN_REQUEST = 'LOGIN_REQUEST'
|
||||
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
|
||||
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
|
||||
|
||||
export function login(username, password) {
|
||||
return { type: LOGIN_REQUEST, username, password }
|
||||
}
|
||||
|
||||
export function loginFailure(username, error) {
|
||||
return { type: LOGIN_FAILURE, username, error }
|
||||
}
|
||||
|
||||
export function loginSuccess(username) {
|
||||
return { type: LOGIN_SUCCESS, username }
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Création de ma saga d'authentification
|
||||
|
||||
```js
|
||||
// src/sagas/auth.js
|
||||
import { call, put } from 'redux-saga/effects';
|
||||
import { loginFailure, loginSuccess } from '../actions/auth';
|
||||
|
||||
export default function* loginSaga(action) {
|
||||
let result;
|
||||
try {
|
||||
result = yield call(doLogin, action.username, action.password);
|
||||
} catch(err) {
|
||||
yield put(loginFailure(action.username, err));
|
||||
}
|
||||
|
||||
if ('error' in result) {
|
||||
yield put(loginFailure(action.username, result.error));
|
||||
return
|
||||
}
|
||||
|
||||
yield put(loginSuccess(action.username));
|
||||
}
|
||||
|
||||
function doLogin(username, password) {
|
||||
return fetch('http://my-backend.org/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
Username: username,
|
||||
Password: password
|
||||
}),
|
||||
mode: 'cors',
|
||||
credentials: 'include'
|
||||
}).then(res => res.json())
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mise en application
|
||||
|
||||
---
|
||||
|
|
Loading…
Reference in New Issue