>  기사  >  웹 프론트엔드  >  React 실제 프로젝트 사례에 대한 자세한 설명(3)

React 실제 프로젝트 사례에 대한 자세한 설명(3)

黄舟
黄舟원래의
2017-07-24 15:58:281420검색

React는 Github에서 거의 70,000개의 별을 보유하고 있으며 현재 가장 인기 있는 프런트 엔드 프레임워크입니다. 한동안 React를 배워왔는데, 이제 React+Redux로 연습을 시작하게 되었습니다!

지난번에는 상태 관리를 위해 Redux를 사용하는 방법에 대해 이야기했습니다. 이번에는 Redux-saga를 사용하여 Redux 애플리케이션의 비동기 작업을 관리합니다.

React 연습 프로젝트(1)

React 연습 프로젝트(2)

React 연습 프로젝트( 3)

- 먼저 로그인된 Reducer

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
  }
};

Saga를 살펴보고 시작된 작업을 모니터링한 다음 이 작업을 기반으로 무엇을 할지 결정합니다. 비동기 호출(예: Ajax)을 시작할지 여부를 결정합니다. 요청), 스토어에 다른 작업을 시작하거나 다른 Sagas를 호출하는 것입니다.

특정 로그인 기능은 로그인 팝업 창을 클릭하면 LOGIN_USER 작업이 실행된다는 것입니다. Sagas는 LOGIN_USER 작업을 모니터링하고 Ajax 요청을 시작합니다. 결과적으로 LOGIN_USER_SUCCESSaction 또는 LOGIN_USER_FAILUREactionLOGIN_USER action,Sagas 监听到 LOGIN_USER action,发起一个 Ajax 请求到后台,根据结果决定发起 LOGIN_USER_SUCCESSaction 还是LOGIN_USER_FAILUREaction

接下来,我们来实现这个流程

  • 创建 Saga middleware 连接至 Redux store

在 package.json 中添加 redux-saga 依赖

"redux-saga": "^0.15.4"

修改 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 使用 Generator 函数实现

  • 监听 action

创建 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)
  ];
}

我们可以看到在 rootSaga 中监听了两个 action 登陆和注册 。

在上面的例子中,takeLatest 只允许执行一个 loginUserAsync 任务。并且这个任务是最后被启动的那个。 如果之前已经有一个任务在执行,那之前的这个任务会自动被取消。

如果我们允许多个 loginUserAsync 实例同时启动。在某个特定时刻,我们可以启动一个新 loginUserAsync 任务, 尽管之前还有一个或多个 loginUserAsync 尚未结束。我们可以使用 takeEvery 辅助函数。

  • 发起一个 Ajax 请求

  • 获取 Store state 上的数据

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));
};
  • 创建 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) 用于获取Store state 上的数据
put(action) 发起一个 action 到 Store
call(fn, ...args)

다음으로 이 프로세스를 구현해 보도록 하겠습니다

  • Saga 미들웨어를 생성합니다. 패키지에서 Redux 스토어

에 연결합니다. json


"redux-saga": "^0.15.4"

redux-saga 종속성을 추가합니다. src/redux/store/store.js 수정🎜rrreee🎜Redux-saga는 생성기 기능을 사용하여🎜🎜🎜🎜listening action🎜🎜🎜🎜Create src/redux/sagas/sagas.js🎜을 구현합니다. rrreee🎜rootSaga에서 로그인 및 등록에 대한 두 가지 작업이 모니터링되는 것을 볼 수 있습니다. 🎜🎜위의 예에서 takeLatest는 하나의 loginUserAsync 작업만 실행되도록 허용합니다. 그리고 이 작업이 마지막으로 시작되는 작업입니다. 이전에 이미 실행 중인 작업이 있는 경우 이전 작업은 자동으로 취소됩니다. 🎜🎜여러 loginUserAsync 인스턴스가 동시에 시작되도록 허용하는 경우. 하나 이상의 이전 loginUserAsync 작업이 아직 완료되지 않은 경우에도 특정 순간에 새 loginUserAsync 작업을 시작할 수 있습니다. takeEvery 도우미 기능을 사용할 수 있습니다. 🎜🎜🎜🎜Ajax 요청 시작🎜🎜🎜🎜스토어 상태에 대한 데이터 가져오기🎜🎜🎜🎜selectors.js🎜rrreee🎜🎜🎜api🎜🎜🎜🎜api.js🎜rrreee🎜 🎜 🎜src/redux/sagas/ 생성 users.js🎜🎜🎜rrreee🎜select(selector, ...args)는 Store 상태에 대한 데이터를 가져오는 데 사용됩니다.🎜put(action)은 다음 작업을 시작합니다. Store🎜 call(fn, ...args)는 args를 매개변수로 사용하여 fn 함수를 호출합니다. 결과가 Promise이면 미들웨어는 Promise가 해결될 때까지 일시 중지됩니다. 계속 실행하게 됩니다. 또는 Promise가 거부될 때까지 생성기에서 오류가 발생합니다. 🎜🎜Redux-saga 상세 API 문서🎜🎜🎜🎜결론🎜🎜🎜🎜저는 직장에서 Redux-Thunk를 사용하는데, Redux-Thunk가 상대적으로 구현과 유지 관리가 더 쉽습니다. 그러나 복잡한 작업, 특히 복잡한 비동기 작업에 직면한 경우 Redux-saga는 더 많은 이점을 가지고 있습니다. 이 시점에서 우리는 Redux-saga에 대한 입문 튜토리얼을 완료했습니다. Redux-saga에는 멋진 점이 많이 있습니다. 🎜🎜🎜

위 내용은 React 실제 프로젝트 사례에 대한 자세한 설명(3)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.