React 实践项目 (二) redux + immutable + redux-saga

React在Github上已经有靠近70000的 star 数了,是如今最热点的前端框架。而我进修React也有一段时间了,如今就最先用 React+Redux 举行实战!

React 实践项目 (一)

本次实践代码

布置好的网址

上回说到用React写了一个带Header的首页,我们此次实践就运用Redux举行状况治理

《React 实践项目 (二) redux + immutable + redux-saga》

Rudex

运用中所有的 state 都以一个对象树的情势储存在一个单一的 store 中。
唯一转变 state 的方法是触发 action,一个形貌发作什么的对象。
为了形貌 action 怎样转变 state 树,你须要编写 reducers。

我们接下来最先最先举行上岸与注册的状况治理

首先在 src 目次下建立 redux 文件夹,目次以下

digag
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   └── favicon.ico
│   └── index.html
│   └── manifest.json
└── src
    └── components
        └── Index
            └── Header.js
            └── LoginDialog.js
            └── RegisterDialog.js
    └── containers
        └── App
            └── App.js
            └── App.css
    └── redux
        └── action
            └── users.js
        └── reducer
            └── auth.js
            └── users.js
        └── sagas
            └── api.js
            └── sagas.js
            └── selectors.js.js
            └── users.js
        └── store
            └── store.js
    └── App.test.js
    └── index.css
    └── index.js
    └── logo.svg
    └── registerServiceWorker.js

代码可今后猎取

记得在 package.json 中更新依靠

接下来我会最先诠释症结代码

  • action
    action/users.js

/*
 * action 范例
 */
export const REGISTER_USER = 'REGISTER_USER';
// 省略其他action 范例

/*
 * action 建立函数
 */
export const registerAction = (newUser) => {
  return{
    type:REGISTER_USER,
    data: newUser,
  }
};
// 省略其他 action 建立函数
  • reducer
    reducer/users.js

//Immutable Data 就是一旦建立,就不能再被变动的数据。
//对 Immutable 对象的任何修正或增加删除操纵都邑返回一个新的 Immutable 对象。
import Immutable from 'immutable';
//从 action 导入须要的 action 范例
import {REGISTER_USER, REGISTER_USER_SUCCESS, REGISTER_USER_FAILURE} from '../action/users';

// 初始化状况
const initialState = Immutable.fromJS({
  newUser: null,
  error: null,
  saveSuccess: false,
});

//  reducer 就是一个纯函数,吸收旧的 state 和 action,返回新的 state。
export const users = (state = initialState, action = {}) => {
  switch (action.type) { // 推断 action 范例
    case REGISTER_USER:  
      return state.merge({   // 更新状况
        'newUser': action.data,
        'saveSuccess': false,
        'error': null,
      });
    case REGISTER_USER_SUCCESS:
      return state.set('saveSuccess', action.data);
    case REGISTER_USER_FAILURE:
      return state.set('error', action.data);
    default:
      return state
  }
};
  • store
    store/store.js

import {createStore, combineReducers, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga'
import * as reducer from '../reducer/users';

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

const sagaMiddleware = createSagaMiddleware();

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

sagaMiddleware.run(rootSaga);

export default store;

然后在进口文件运用 store

src/index.js

import {Provider} from 'react-redux';
import store from './redux/store/store';
// 省略其他

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>, document.getElementById('root')
);

在 App.js 中猎取 action 和 状况

import {registerAction, loginAction} from '../../redux/action/users';
import {connect} from "react-redux";
import {bindActionCreators} from "redux";
 //省略其他

class App extends Component {

  render(){
    return(
      <div className="App">
        //省略
      </div>
    )
  }

}

export default connect(
  (state) => {
// 猎取状况   state.users  是指 reducer/users.js 文件中导出的 users
// 能够 `console.log(state);` 检察状况树
  return { users: state.users }
},
  (dispatch) => {
  return {
// 建立action
    registerActions: bindActionCreators(registerAction, dispatch),
    loginActions: bindActionCreators(loginAction, dispatch),
  }
})(App);
// 在App 组件的props里就有 this.props.users  this.props.registerActions this.props.loginActions 了
// 须要注重的是这里this.props.users是Immutable 对象,取值须要用this.props.users.get('newUser') 
// 也可在 reducer 里改用 js 一般对象

装潢器版本:
须要在Babel中开启装潢器
装潢器插件babel-plugin-transform-decorators-legacy

@connect(
  (state) => {
    console.log(state);
    return ({
      users: state.users,
    });
  },
  {registerActions: registerAction, loginActions: loginAction}
)

末了把 registerActions 传给RegisterDialog子组件,

src/components/Index/RegisterDialog.js

// 省略其他代码
 handleSubmit = (e) => {
    e.preventDefault();
    // 考证表单数据
    this.refs.user.validate((valid) => {
      if (valid) {
        // this.state.user 为表单网络的 用户注册数据
        this.props.registerActions(this.state.user);
        this.setState({loading: true});
      }
    });
  };

流程是:

  • 挪用 action

    `this.props.registerActions(this.state.user);`
     返回action 为 
{
    type:REGISTER_USER,
    data: this.state.user,
}
  • reducer 依据action范例更新状况

switch (action.type) {
    case REGISTER_USER:
      return state.merge({
        'newUser': action.data,
        'saveSuccess': false,
        'error': null,
      });
//省略其他代码

这时候我们的store里的状况 newUser 就被更新为 注册弹窗里网络的数据
到这里都照样同步的action,而注册是一个异步的操纵。
下篇文章会引见怎样运用 redux-saga 举行异步操纵。
redux-saga 已经在运用了,有兴致的能够自行检察代码明白。

记得点star:)
项目代码地点:https://github.com/DigAg/diga…
vue2版项目代码地点:https://github.com/DigAg/diga…
响应后端项目代码地点:https://github.com/DigAg/diga…

    原文作者:Yuicon
    原文地址: https://segmentfault.com/a/1190000010108518
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞