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