1. 程式人生 > >React-Dva學習

React-Dva學習

安裝

  • 安裝腳手架
npm install dva-cli -g
or
yarn global add dva-cli
  • 建立新應用

安裝完cli工具以後就可以在命令列訪問到,

為了方便學習,我們可以使用命令建立

// 建立一個標準專案
 dva new my-app
// 建立一個學習的 簡答的demo
dva new my-app --demo

  • 啟動專案

進入專案目錄,執行啟動命令,啟動開發伺服器

// 啟動專案
npm start 0r yarn start

// 等到看到以下資訊輸出,就可以啟動專案了
Compiled successfully!
The app is running at:
 http://localhost:8000/

使用antd

  • 安裝antd

通過 npm 安裝 antdbabel-plugin-importbabel-plugin-import 是用來按需載入 antd 的指令碼和樣式的,

npm install antd babel-plugin-import --save
Or 
yarn add antd babel-plugin-import --save
  • 編輯 .webpackrc,使 babel-plugin-import 外掛生效。
{
+  "extraBabelPlugins": [
+    ["import"
, { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] + ] }

注:dva-cli 基於 roadhog 實現 build 和 dev,更多 .webpackrc 的配置詳見 roadhog#配置

定義路由

  • 新建檔案,建立路由表
// 1.在src下新建pages目錄
// 2.新建在src/pages新一個js檔案,命名名為Login.js
// 3.src/pages/Login.js 檔案內容如下

import React from 'react';

const Login
= (props) => ( <h2>Login</h2> ); export default Login;
  • 新增路由資訊到路由表
// routers.js 新增一下程式碼
// 引入模板
import Login from './pages/Login'

// 新增Route
<Route path="/login" exact component={Login} />

現在就可以在瀏覽器檢視路徑了

定義model

  • model是一個物件,提供了註冊model方法app.model({}),取消註冊方法app.unmodel(namespace), 需要特別注意的是: 取消 model 註冊,清理 reducers, effects 和 subscriptions。subscription 如果沒有返回 unlisten 函式,使用 app.unmodel 會給予警告

  • namespace:,字串,名稱空間,我們在對該model進行CRUD的時候通過這個空間來方法具體的資料或者actions

  • reducers: 一個物件, 裡邊方react-redux裡的dispatch函式,我們出發同步的action,然後經過reducers裡對應的函式處理,然後更新store

  • effects: 物件,副作用。當我們在開發的時候如果有非同步的操作,會先出發effects裡的函式,然後拿到結果以後再出發reducers裡的同步函式對store進行CRUD

  • subscriptions:物件, 訂閱 在這裡我們監聽url變化,當切換到todos的時候,呼叫後臺介面非同步渲染資料

  • 下邊是一個簡單的model

// model demo
app.model({
  // 名稱空間,它就是之前combineReducers裡邊的key值
  namespace: 'counter',
  state: { // 狀態
    number: 0
  },
  // 處理器, 這裡可以直接定義子reducer
  reducers: {
    // 這個函式會在派發一個動作 'counter/add'的時候觸發add函式
    add (state, action) {
      return {number: state.number + 1}
    },
    minus (state, action) {
      return { number: state.number - 1 }
    }
  }
})

定義元件元件

dva裡所有的元件都是函式元件,只有在特殊情況下,如需要宣告週期的元件才會使用類元件

定義一個簡單的元件如下:

function Counter({ number, dispatch}) {
  return (
    <div>
      <p>{number}</p>
      <button onClick={()=> dispatch({type: 'counter/add'})} >add</button>
      {/* <button onClick={add} >add</button> */}
    </div>
  )

actions派發

let actions = {
  add () {
    return {
      type: 'counter/add'
    }
  }, 
  mins () {
    return {
      type: 'counter/minus'
    }
  }
}

// 使用connect連線
let mapStatetoProps = state => state.counter
let ConnectCounter = connect(
  mapStatetoProps
)(Counter)

配置動態載入元件

 import dynamic from 'dva/dynamic';

const UserPageComponent = dynamic({
  app,
  models: () => [
    import('./models/users'),
  ],
  component: () => import('./routes/UserPage'),
});

來一個栗子

  • 使用dva初始化一個demo專案,在這個demo的基礎上寫一個技術的小練習

  • 初始化專案, dva new counter --demo

  • 進入counter/src/index.js

  • 開始改寫

import React, {Component} from 'react';
import dva, { connect } from 'dva'

let app = dva()
// combineReducers({
//   counter: counter
// })
 // state 合成後的樣子
//  {
//    counter: {number: 1}
//  }

// 配置模型
app.model({
  // 名稱空間,它就是之前combineReducers裡邊的key值
  namespace: 'counter',
  state: { // 狀態
    number: 0
  },
  // 處理器, 這裡可以直接定義子reducer
  reducers: {
    // 這個函式會在派發一個動作 'counter/add'的時候觸發add函式
    add (state, action) {
      return {number: state.number + 1}
    },
    minus (state, action) {
      return { number: state.number - 1 }
    }
  }
})


// 使用action派發
let actions = {
  add () {
    return {type: 'counter/add'}
  }, 
  mins () {
    return {type: 'counter/minus'}
  }
}

// 定義元件, dva裡所有的元件都是函式元件 
// function Counter({ number, dispatch}) { // 之前寫法
//   return (
//     <div>
//       <p>{number}</p>
//       <button onClick={()=> dispatch({type: 'counter/add'})} >add</button>
//       {/* <button onClick={add} >add</button> */}
//     </div>
//   )
// }
function Counter({ number, add }) {// dva的寫法
  return (
    <div style={{border: '1px solid #06c', width: 200, height: 3 00, margin: '100px auto 0', padding: 20}}>
      <p>{number}</p>
      <button onClick={add} >add</button>
    </div>
  )
}
// 使用connect連線
let mapStatetoProps = state => state.counter
// let ConnectCounter = connect(
//   mapStatetoProps
// )(Counter)

// 使用actions派發動作
let ConnectCounter = connect(
  mapStatetoProps,
  actions
)(Counter)
// 定義路由
app.router((history, app) => (
  <div>
    <ConnectCounter />
  </div>
))
// 啟動程式
app.start('#root')
  • 啟動專案,就能看到效果了

總結

以上是一個簡單的dva的使用介紹,以及一個計數器的小栗子,後邊再寫一個todoList,用來深入的理解dva的使用和資料流