首頁 > web前端 > js教程 > 主體

分享一個React的實踐項目

零下一度
發布: 2017-07-23 18:09:34
原創
1845 人瀏覽過

上回說到用React寫了一個有Header的首頁,我們這次實踐就使用Redux進行狀態管理

分享一個React的實踐項目

Rudex

應用程式中所有的state 都以一個物件樹的形式儲存在單一的store 中。
惟一改變 state 的辦法是觸發 action,一個描述發生什麼事的物件。
為了描述 action 如何改變 state 樹,你需要寫 reducers。

我們接下來開始開始進行登陸與註冊的狀態管理

首先在 src 目錄下建立 redux 資料夾,目錄如下

digag
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   └── favicon.ico
│   └── 分享一個React的實踐項目.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
    └── 分享一個React的實踐項目.css
    └── 分享一個React的實踐項目.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/分享一個React的實踐項目.js
    import {Provider} from 'react-redux';
    import store from './redux/store/store';
    // 省略其他
    
    ReactDOM.render(
      <provider>
        <app></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>
            //省略
          </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,而註冊是一個非同步的操作。 ######

    以上是分享一個React的實踐項目的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    相關標籤:
    來源:php.cn
    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    最新問題
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板