什么是dva?
dva集成了react + redux + saga , 让这三个东西看起来更加的“统一”,大变了语法风格和整个项目的架构。
基本使用
先来一份目录结构:
test |-www |-index.html |-app |-App.js |-main.js |-package.json |-webpack.config.js
1.起步
dva的起步非常简单:
1)要创建一个app对象,非常类似express
2)用app.router定义一个路由
3)用app.start()来上树。
main.js代码如下:import React from "react";
import ReactDOM from "react-dom";
import dav from "dva"
const app = dva();
app.router(()=>{
return <h1>Hello dva</h1>
});
app.start("app");
2.组件
组件没有改变,所以组件的生命周期也没有改变,组件的state、props都没有任何改变。
3.配置store
我们知道redux就是全局的数据中心,dva全面简化了这一套东西。
创建models文件夹,创建counter.js文件:
目录结构如下:
test
|-www
|-index.html
|-app
|-App.js
|-main.js
|-models
|-.counter.js
|-package.json
|-webpack.config.js
export default { |
即,我们之前的reducers里面的export default (state= {"v" : 100} , action){
}
这套东西现在变为了一个纯对象,我们称为model。
model必须有namespace,表示命名空间,就是原来说的combineReducers的命名空间。
在main.js中引入数据
main.js:import React from "react";
import dva from "dva";
import App from "./App.js";
// 引入数据
import counter from "./models/counter.js";
//创建app
const app = dva();
//配置store
app.model(counter);
//配置路由
app.router(() => <App />);
//上树
app.start("#app");
组件几乎没有改变得到值的写法,还是需要connect,但是需要从dva中引包:import React from "react";
import {connect} from "dva";
class App extends React.Component{
constructor(){
super();
}
render(){
return <div>
<h1>{this.props.v}</h1>
</div>
}
}
export default connect(
({counter}) => ({
v: counter.v
})
)(App);
dva帮我们combineReducers了。
4.dispatch一个action
全面简化了!
现在组件可以直接this.props.dispatch()东西了。而不用调用一个外置的action文件了,更不用bindActionCreators了。import React from "react";
import {connect} from "dva";
class App extends React.Component{
constructor(){
super();
}
render(){
return <div>
<h1>{this.props.v}</h1>
<button onClick={()=>{
this.props.dispatch({"type" : "counter/ADD"});
}}>按我加1</button>
<button onClick={()=>{
this.props.dispatch({"type" : "counter/MINUS"});
}}>按我减1</button>
</div>
}
}
export default connect(
({counter}) => ({
v: counter.v
})
)(App);
dva中connect()()没有第二个参数!!!
dispatch里面的内容是{“type” : “命名空间/大写字母” , 载荷}
5.异步
dva中saga自动运行,自动拦截!
model文件中:
- reducers里面写没有副作用,类似之前的reducers文件。
- effects里面写有副作用的东西,都是加星函数,类似之前的saga文件。
即,saga文件现在和reducer合二为一了。
export default {
namespace : "counter" ,
state : {
v : 100
},
reducers : {
ADD(state , action){
return {
...state ,
"v" : state.v + (action.a || 1)
}
},
MINUS(state , action){
return {
...state,
"v" : state.v - 1
}
}
},
effects : {
*ADDSERVER(action , {put}){
const {a} = yield fetch("/api/api").then(data=>data.json());
yield put({ "type": "ADD" , a});
},
*JBOBB(action , {put , select}){
const {v} = yield select(state => state.counter);
if(v % 2 == 1){
yield put({ "type": "ADD"});
}
}
}
}