Home  >  Article  >  Web Front-end  >  Detailed explanation of examples of React practical projects (3)

Detailed explanation of examples of React practical projects (3)

黄舟
黄舟Original
2017-07-24 15:58:281421browse

React has nearly 70,000 stars on Github and is currently the most popular front-end framework. I have been learning React for a while, and now I am starting to practice it with React+Redux!

Last time we talked about using Redux for state management. This time we use Redux-saga to manage Redux application asynchronous operations

React Practice Project (1)

React Practice Project (2)

React Practice Project (3)

- First, let’s take a look at the logged-in 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
  }
};

Sagas to monitor the action initiated, and then decide What to do based on this action: whether to initiate an asynchronous call (such as an Ajax request), initiate other actions to the Store, or even call other Sagas.

Specifically, this login function will issue a LOGIN_USER action when we click on the login pop-up window. Sagas monitors the LOGIN_USER action and initiates an Ajax request to the background. , decide to initiate LOGIN_USER_SUCCESSaction or LOGIN_USER_FAILUREaction

based on the result

  • Next, let’s implement this process

Create Saga Middleware connects to Redux store

Add redux-saga dependency in package.json

"redux-saga": "^ 0.15.4"

Modify

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 uses Generator function to implement

Listening action

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

We can see that two actions are monitored in rootSaga: login and register.

    In the above example, takeLatest only allows one loginUserAsync task to be executed. And this task is the last one to be started. If there is already a task being executed before, the previous task will be automatically canceled.
  • If we allow multiple loginUserAsync instances to start at the same time. At a certain moment, we can start a new loginUserAsync task, even though one or more previous loginUserAsync tasks have not yet completed. We can use the takeEvery helper function.

  • Initiate an Ajax request

Get the data on 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));
    };

Create 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)
Used to obtain data on Store stateput(action)

Initiate an action to the Store

call(fn, ...args)
    Call the fn function with args as the parameter. If the result is a Promise, the middleware will pause until the Promise is resolved. After resolution, the Generator will continue to be executed. Or until the Promise is rejected, in which case an error will be thrown in the Generator.
  • Redux-saga detailed api documentation

Conclusion

###I use Redux-Thunk at work, Redux- Thunk is relatively easier to implement and maintain. But for complex operations, especially when faced with complex asynchronous operations, Redux-saga has more advantages. At this point we have completed an introductory tutorial for Redux-saga. Redux-saga still has many wonderful things, #########

The above is the detailed content of Detailed explanation of examples of React practical projects (3). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn