dva構築簡易reactプロジェクト実践総括

18794 ワード

目次
1.はじめに
2.ツール&環境&学習資料
3.足場の取り付け&reactプロジェクトの作成
4.設計
4.1抽出モデル
4.2コンポーネントとルーティングの設計
4.3 Reducersの追加
4.4 Effectsの追加
4.5サービスの分離
1.はじめに
師匠が与えた方向によって、dva-cliという足場ツールを学び、Reactプロジェクトの開発を行いました.インターネットで学習チュートリアルを検索する過程で、間違いなく「12歩30分、ユーザー管理のCURDアプリケーション(react+dva+antd)」というチュートリアルの文章を閲覧したことがある.しかし、私の実際の学習では、個人のソフトウェア環境(nodeバージョンと呼ばれる)の問題のためか、以下のdvaコマンドラインを使用するときに頻繁にエラーを報告し、チュートリアルに従ってプロジェクトを構築することはできません.
//     users     
dva g route users
//     users model    
dva g model users

そのため、同じ作者の比較的古いバージョンのチュートリアルを見つけて、dvaの紹介の上でもっとはっきりしているような気がして、最新版は本当に焦っています.このチュートリアルに従って実践を完了すると、reactプロジェクト全体のデータ流通プロセスを基本的に理解することができます.
2.ツール&環境&学習資料
  • ツール:dva-cli足場
  • 環境:nodejs 6.11.1&npm 5.3.0
  • 学習チュートリアル:dva-cli構築reactプロジェクトuser-dashboard実践チュートリアル
  • 3.足場の取り付け&reactプロジェクトの作成
    dva構造紹介dva公式中国語ドキュメントdvaを使用するために必要なすべての知識点
    //   dva-cli   
    npm install -g dva-cli
    
    //   dva  react    
    dva new [newProjectName] 
    

    reactプロジェクトの推奨ディレクトリ構造(dva足場を使用して作成すると、以下のように自動的に生成されます)
    |── /mock/             #   mock       
    |── /src/              #       (           )   
    |   |── /components/   #     (               )   
    |   |── /routes/       #     (    ) 
    |   |  |── route1.js  
    |   |  |── route2.js   #   router.js    ,    url ,         
    |   |  └── route3.js    
    |   |── /models/       #     (     store,         )  
    |   |  |── model1.js  
    |   |  |── model2.js   #        model  ,           
    |   |  └── model3.js  
    |   |── /services/     #     (       ajax  ,     )   
    |   |── /utils/        #     (   ,           )     
    |   |── router.js       #     (            )  
    |   |── index.js       #       
    |   |── index.less      
    |   └── index.html     
    |── package.json       #       
    └── proxy.config.js    #   mock    
    

    4.設計
    4.1、Modelを引き離す
    個人的な理解:ここのModelには、ビジネスエンティティのステータスとメソッドが含まれています.modelはjavaのclassとよく似ており、 (state) (effects)が含まれており、外部で自分のプライベート変数を変えることは許されないが、他の場所でModel (effects)を呼び出すことで model ( effect reducer)になることができる.
    Modelを引き離して、ページの需要を設計することによって、相応のModel教程の中の需要を設計するのは1つのユーザーのデータのフォームの展示で、添削して調べるなどの機能を含んでusers模型を提出します
    // models/users.js
    // version1:        ,          
    // version2:        ,                  model
    //              ,               
    export default {
      namespace: 'users',
      state: {
        list: [],
        total: null,
    +   loading: false, //       
    +   current: null, //       
    +   currentItem: {}, //          
    +   modalVisible: false, //         
    +   modalType: 'create', //       (    ,    )
      },
    
        //     
        effects: {
            *query(){},
            *create(){},
            *'delete'(){},   //   delete    ,    
            *update(){},
        },
    
        //      
        reducers: {
    +       showLoading(){}, //         reducer
    +       showModel(){}, //    Model       reducer
    +       hideModel(){},
            querySuccess(){},
            createSuccess(){},
            deleteSuccess(){},
            updateSuccess(){},
        }
    }
    
    

    4.2、設計コンポーネント
    コンテナコンポーネントのアクセスパスを設定してから、コンポーネントファイルを作成します.
    4.2.1二つの構成要素の概念:容器構成要素と展示構成要素
  • コンテナコンポーネント:データを傍受する動作を有するコンポーネントであり、関連するmodelデータをバインドし、サブコンポーネントを含む役割を果たす.入力データはmodel
  • に由来する
    import React, { Component, PropTypes } from 'react';
    
    // dva   connect                
    import { connect } from 'dva';
    
    //     
    const MyComponent = (props)=>{};
    
    // propTypes  ,    props       
    MyComponent.propTypes = {};
    
    //         ,              
    //       ModelA       ,         ,       ,      ModelA    
    //       Model
    function mapStateToProps({ModelA}) {
      return {ModelA};
    }
    
    //    model
    //           ,      
    export default connect(mapStateToProps)(MyComponent);
    
    
  • 展示コンポーネント:propsを通じてコンポーネント内部に伝達されたデータを展示する.入力データは、コンテナコンポーネントからディスプレイコンポーネントへのprops
  • に由来する.
    import React, { Component, PropTypes } from 'react';
    
    //     
    //          Container Component    props     
    const MyComponent = (props)=>{}
    MyComponent.propTypes = {};
    
    //        
    export default MyComponent;
    

    4.2.2ルーティングの設定
    // .src/router.js
    import React, { PropTypes } from 'react';
    import { Router, Route } from 'dva/router';
    import Users from './routes/Users';
    
    export default function({ history }) {
      return (
        
          
        
      );
    };
    
    

    コンテナアセンブリの雛形
    // .src/routes/Users.jsx
    import React, { PropTypes } from 'react';
    
    function Users() {
      return (
        
    User Router Component
    ); } export default Users;

    4.2.3起動項目
  • npm start開始項目
  • ブラウザは、localhost:8000/#/usersを開き、新規ルーティングおよびルーティングのコンポーネント
  • を表示する.
    4.2.4設計容器アセンブリ
    上から下への設計方法:まず容器コンポーネントを設計し、内部の展示容器を徐々に細分化する.
    コンポーネントの定義方法:
    //    : es6    ,     react     ,       
    //          ,             ,       ,        
    //           xx  (componentDidMount)、             (shouldComponentUpdate) 
    class App extends React.Component({});
    
    //    : stateless    ,       
    //      ,           ,         
    const App = (props) => ({});
    

    コンテナコンポーネント:
    // ./src/routes/Users.jsx
    import React, { Component, PropTypes } from 'react';
    
    //        (      )
    import UserList from '../components/Users/UserList';
    import UserSearch from '../components/Users/UserSearch';
    import UserModal from '../components/Users/UserModal';
    
    //   css   
    import styles from './style.less'
    
    function Users() {
    
      //  userListProps       
      const userSearchProps = {};
      const userListProps = {
        total: 3,
        current: 1,
        loading: false,
        dataSource: [
          {
            name: '  ',
            age: 23,
            address: '  ',
          },
          {
            name: '  ',
            age: 24,
            address: '  ',
          },
          {
            name: '  ',
            age: 25,
            address: '  ',
          },
        ],
      };
      const userModalProps = {};
    
      return (
        
    {/* */} {/* */} {/* & */}
    ); } // export; import export default Users;

    展示コンポーネントUserList
    // ./src/components/Users/UserList.jsx
    import React, { Component, PropTypes } from 'react';
    
    //   antd UI  
    import { Table, message, Popconfirm } from 'antd';
    
    //    stateless    
    const UserList = ({
        total,
        current,
        loading,
        dataSource,
    }) => {
      const columns = [{
        title: '  ',
        dataIndex: 'name',
        key: 'name',
        render: (text) => {text},
      }, {
        title: '  ',
        dataIndex: 'age',
        key: 'age',
      }, {
        title: '  ',
        dataIndex: 'address',
        key: 'address',
      }, {
        title: '  ',
        key: 'operation',
        render: (text, record) => (
          

    {}}}> {}}>

    ), }]; // const pagination = { total, current, pageSize: 10, onChange: ()=>{}, }; // Table antd , antd // index.js antd import 'antd/dist/antd.css' return (
    record.id} pagination={pagination} /> ); } export default UserList;

    4.3 Reducer

    model reducer model state , ;
    return {...state}

    4.3.1 : reducer
    // models/users.js
    //         , userList          
    // querySuccess  action     ,   model   
    export default {
      namespace: 'users',
      state: {},
      subscriptions: {},
      effects: {},
      reducers: {
        querySuccess(state){
            const mock = {
              total: 3,
              current: 1,
              loading: false,
              list: [
                {
                  id: 1,
                  name: '  ',
                  age: 23,
                  address: '  ',
                },
                {
                  id: 2,
                  name: '  ',
                  age: 24,
                  address: '  ',
                },
                {
                  id: 3,
                  name: '  ',
                  age: 25,
                  address: '  ',
                },
              ]
            };
            // return         ,   state      ,   “    ”   
            return {...state, ...mock, loading: false};
          }
      }
    }
    
    
    4.3.2 2ステップ: Modelのデータソース
    // routes/Users.jsx
    
    import React, { PropTypes } from 'react';
    
    //      connect  ,         connect
    import { connect } from 'dva';
    
    function Users({ location, dispatch, users }) {
    
      const {
        loading, list, total, current,
        currentItem, modalVisible, modalType
        } = users;
    
      const userSearchProps={};
    
      //         ,      
      const userListProps={
        dataSource: list,
        total,
        loading,
        current,
      };
      const userModalProps={};
    
      return (
        
    {/* */} {/* */} {/* & */}
    ); } // props Users.propTypes = { users: PropTypes.object, }; // , users function mapStateToProps({ users }) { return {users}; } // export default connect(mapStateToProps)(Users);
    4.3.3 3ステップ:Actionを することによって、Modelのデータ
    // models/users.js
    //         action,  :
    componentDidMount() {
      this.props.dispatch({
        type: 'model/action',     // type  action   
      });
    }
    
    //       ,   /users/   ,             
    //    dispatch  subscription 
    // subcription,  (    )     ,      dispatch   action
    //            、     websocket   、keyboard   、geolocation   、history         
    //               ,    /users,   'querySuccess'  effects  
    subscriptions: {
        setup({ dispatch, history }) {
          history.listen(location => {
            if (location.pathname === '/users') {
              dispatch({
                type: 'querySuccess',
                payload: {}
              });
            }
          });
        },
      },
    
    
    ###### 4.3.4    :  index.js   models
    // model        ,      
    // index.js
    app.model(require('./models/users.js'));
    
    4.4をコンポーネントで するEffectsEffectsを することは、 を し、データフローを することにある. のシーンでは、データはすべてサーバから ているので、 リクエストを して り を した にデータを し、stateを する があります.そのため、Effectsでreducerを び すことがよくあります.javaクラスをクラス としてeffectsはpublic に し、 で び すことができますが、reducersはprivate に します.effectsが び されると、reducer が に び され、modelのstateが されます.もちろんeffectsの は び しであり、ajax などの を することである.
    export default {
      namespace: 'users',
      state: {},
      subscriptions: {},
      effects: {
        //   effects  
        // call put dva   
        // call        
        // put  dispatch    action
        // select      model
        *query({ payload }, { select, call, put }) {
            yield put({ type: 'showLoading' });
            const { data } = yield call(query);
            if (data) {
              yield put({
                type: 'querySuccess',
                payload: {
                  list: data.data,
                  total: data.page.total,
                  current: data.page.current
                }
              });
            }
          },
        },
      reducers: {}
    }
    
    
    
    //               ajax  
    // models/users.js
    import request from '../utils/request';
    import qs from 'qs';
    async function query(params) {
      return request(`/api/users?${qs.stringify(params)}`);
    }
    
    
    4.5 をサービスに する はajax
    // services/users.js
    import request from '../utils/request';
    import qs from 'qs';
    export async function query(params) {
      return request(`/api/users?${qs.stringify(params)}`);
    }
    
    //  models   
    // models/users.js
    import {query} from '../services/users';
    
    を することである








    アルファベットで :
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z その