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 安裝
antd
和babel-plugin-import
。babel-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的使用和資料流