Maison >interface Web >js tutoriel >Explication détaillée d'exemples de projets pratiques React (3)

Explication détaillée d'exemples de projets pratiques React (3)

黄舟
黄舟original
2017-07-24 15:58:281456parcourir

React compte près de 70 000 étoiles sur Github et est actuellement le framework front-end le plus populaire. J'apprends React depuis un moment, et maintenant je commence à le pratiquer avec React+Redux !

La dernière fois, nous avons parlé de l'utilisation de Redux pour la gestion de l'état. Cette fois, nous utilisons Redux-saga pour gérer les opérations asynchrones des applications Redux

Projet pratique React (1)

Projet pratique React (2)

Projet pratique React (3)

- Tout d'abord, jetons un coup d'œil aux actions initiées par le réducteur connecté

export const auth = (state = initialState, action = {}) => {
  switch (action.type) {
    case LOGIN_USER:
      return state.merge({
        'user': action.data,
        'error': null,
        'token': null,
      });
    case LOGIN_USER_SUCCESS:
      return state.merge({
        'token': action.data,
        'error': null
      });
    case LOGIN_USER_FAILURE:
      return state.merge({
        'token': null,
        'error': action.data
      });
    default:
      return state
  }
};

Sagas. Décidez ensuite quoi faire en fonction de cette action : lancer un appel asynchrone (comme une requête Ajax), lancer d'autres actions vers le Store, ou même appeler d'autres Sagas.

La fonction de connexion spécifique est que lorsque nous cliquons sur la fenêtre contextuelle de connexion, une action LOGIN_USER sera émise. Sagas surveille l'action LOGIN_USER, lance une requête Ajax en arrière-plan et décide. pour lancer LOGIN_USER_SUCCESS en fonction du résultat action ou LOGIN_USER_FAILUREaction

Ensuite, implémentons ce processus

  • Créons un middleware Saga et connectons-nous à la boutique Redux

Ajouter redux-saga dépendances dans package.json

"redux-saga": "^0.15.4"

Modifier src/redux/store/store.js

/**
 * Created by Yuicon on 2017/6/27.
 */
import {createStore, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga'
import reducer from '../reducer/reducer';

import rootSaga from '../sagas/sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  reducer,
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);

export default store;

Redux-saga utilise la fonction Générateur pour implémenter

  • Action d'écoute

Créer src/redux/sagas/sagas.js

/**
 * Created by Yuicon on 2017/6/28.
 */
import { takeLatest } from 'redux-saga/effects';
import {registerUserAsync, loginUserAsync} from './users';
import {REGISTER_USER, LOGIN_USER} from '../action/users';

export default function* rootSaga() {
  yield [
    takeLatest(REGISTER_USER, registerUserAsync),
    takeLatest(LOGIN_USER, loginUserAsync)
  ];
}

On voit qu'il est surveillé dans rootSaga. Les deux actions sont la connexion et l'enregistrement.

Dans l'exemple ci-dessus, takeLatest autorise l'exécution d'une seule tâche loginUserAsync. Et cette tâche est la dernière à être lancée. Si une tâche est déjà en cours d'exécution auparavant, la tâche précédente sera automatiquement annulée.

Si nous autorisons le démarrage de plusieurs instances loginUserAsync en même temps. À un certain moment, nous pouvons démarrer une nouvelle tâche loginUserAsync, même si une ou plusieurs tâches loginUserAsync précédentes ne sont pas encore terminées. Nous pouvons utiliser la fonction d'assistance takeEvery.

  • Lancer une requête Ajax

  • Obtenir les données sur l'état du magasin

selectors.js

/**
 * Created by Yuicon on 2017/6/28.
 */
export const getAuth = state => state.auth;
  • api

api.js

/**
 * Created by Yuicon on 2017/7/4.
 * 
 */

/**
 * 这是我自己的后台服务器,用 Java 实现
 * 项目地址:
 * 文档:http://139.224.135.86:8080/swagger-ui.html#/
 */
const getURL = (url) => `http://139.224.135.86:8080/${url}`;

export const login = (user) => {
  return fetch(getURL("auth/login"), {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(user)
  }).then(response => response.json())
    .then(json => {
      return json;
    })
    .catch(ex => console.log('parsing failed', ex));
};
  • Créer src/redux/ sagas/users.js

/**
 * Created by Yuicon on 2017/6/30.
 */
import {select, put, call} from 'redux-saga/effects';
import {getAuth, getUsers} from './selectors';
import {loginSuccessAction, loginFailureAction, registerSuccessAction, registerFailureAction} from '../action/users';
import {login, register} from './api';
import 'whatwg-fetch';

export function* loginUserAsync() {
  // 获取Store state 上的数据
  const auth = yield select(getAuth);
  const user = auth.get('user');
  // 发起 ajax 请求
  const json = yield call(login.bind(this, user), 'login');
  if (json.success) {
    localStorage.setItem('token', json.data);
    // 发起 loginSuccessAction
    yield put(loginSuccessAction(json.data));
  } else {
    // 发起 loginFailureAction
    yield put(loginFailureAction(json.error));
  }
}

select(selector, ...args) Utilisé pour obtenir des données sur l'état du magasin
put(action) Lancer une action pour stocker
call(fn, ...args) Appeler fn Le La fonction prend des arguments comme paramètres. Si le résultat est une promesse, le middleware fera une pause jusqu'à ce que la promesse soit résolue, et le générateur poursuivra son exécution après la résolution. Ou jusqu'à ce que la promesse soit rejetée, auquel cas une erreur sera générée dans le générateur.

Documentation détaillée de l'API Redux-saga

  • Conclusion

J'utilise Redux-Thunk au travail, Redux-Thunk est relativement plus facile à mettre en œuvre et à entretenir. Mais pour les opérations complexes, en particulier face à des opérations asynchrones complexes, Redux-saga présente plus d'avantages. À ce stade, nous avons terminé un didacticiel d'introduction à Redux-saga. Il y a beaucoup de choses merveilleuses à propos de Redux-saga,

.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn