1、為什麼學習react-dva
- 之前的react的專案,webpack、redux、redux-saga都是自己寫,用過的人都明白,首先redux真的是很麻煩
- 來回幾個action,action-type,reducer來回切換,非同步外掛react-thunk雖然簡單,但一些複雜場景還是不好用,而且給action帶來了副作用,後來瞭解到react-dva,確實寫起來要效率高很多
2、demo專案簡介
點選+號按鈕,立即+1,但過一秒之後(非同步操作),就減一
3、如何搭建dva專案
3.1 安裝dva-cli
$ npm install dva-cli -g
$ dva -v
dva-cli version 0.9.1
複製程式碼
3.2 建立新應用
$ dva new counter
// 建立完畢就進入到counter專案,並啟動伺服器
$ cd counter
$ npm start
複製程式碼
4、先完成專案樣式的佈局
4.1 改寫src目錄下的index.js的路由
// index.js
import Counter from './components/Counter'
app.router(({ history }) => {
return (
<Router history={history}>
<Switch>
<Route path='/' exact component={Counter} />
</Switch>
</Router>
)
});
複製程式碼
接著初始化index.js裡的reducer裡的資料
app.model({
namespace: 'count',
state: {
current: 0
},
reducers: {
add(state, action) {
let newCurrent = state.current + 1
return { current: newCurrent }
}
}
})
// namespace代表名稱空間,也就是這個reducer的名字叫count
// state代表初始化資料是一個物件,物件裡的屬性是current:0
// reducer就跟我們平時用的reducer一樣,add代表action.type的型別
// add函式裡面的引數有兩個,第一個state就是上面我們定義的state,即{current: 0}
// action 代表觸發的行為型別
複製程式碼
然後進入到components目錄裡,建立Counter.js檔案
import React, { Component } from 'react'
import { connect } from 'dva'
import styles from '../index.less'
class Counter extends Component {
render() {
return (
<div className={styles.container}>
<div className={styles.current}>
{this.props.current}
</div>
<div className={styles.button}>
<button onClick={() => this.props.dispatch({ type: 'count/add' })}>+</button>
</div>
</div>
)
}
}
export default connect(
state => state.count
)(Counter)
// 這裡connect函式跟就是react-redux裡面的connect函式,目的是用來連線react和redux的
// styles是給我們的css新增名稱空間的,用法直接照搬就行了
複製程式碼
index.less檔案如下
.container{
width: 200px;
padding: 20px;
border:1px solid #ccc;
box-shadow: 0 0 10px #CCC;
margin: 50px auto;
.current{
padding: 50px 0;
text-align: center;
font-size: 20px;
}
.button{
text-align: center;
button{
width: 100px;
height: 30px;
font-size: 18px;
}
}
}
複製程式碼
這樣,我們第一步,樣式就做出來了,還可以點選加號,有+1的效果了
5、完成專案的非同步操作
非同步操作只需要在app.model裡面增加effects屬性就可以了。 app.modal改造如下
let delay = ms => new Promise((resolve, reject) => {
setTimeout(() => resolve('ok'), ms)
})
app.model({
namespace: 'count',
state: {
current: 0
},
reducers: {
add(state, action) {
let newCurrent = state.current + 1
return { current: newCurrent }
},
minus(state, action) {
let newCurrent = state.current - 1
return { current: newCurrent }
}
},
// 副作用
effects: {
// call呼叫一個方法,put派發一個action
*add(action, { call, put }) {
yield call(delay, 1000)
yield put({ type: 'minus' })
}
}
});
複製程式碼
這裡在effects裡面增加了一個add方法,這個add方法裡面呼叫了reducer裡的minus方法,並且延遲了1秒
到這裡,一個簡單的dva小玩具就完成了