react-dva學習 --- 用例項來入門

lio-mengxiang發表於2019-04-02

1、為什麼學習react-dva

  • 之前的react的專案,webpack、redux、redux-saga都是自己寫,用過的人都明白,首先redux真的是很麻煩
  • 來回幾個action,action-type,reducer來回切換,非同步外掛react-thunk雖然簡單,但一些複雜場景還是不好用,而且給action帶來了副作用,後來瞭解到react-dva,確實寫起來要效率高很多

2、demo專案簡介

點選+號按鈕,立即+1,但過一秒之後(非同步操作),就減一

react-dva學習 --- 用例項來入門

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小玩具就完成了

相關文章