Dva.js 快速上手文档
1. Dva.js 概念
Dva.js 是基于 Redux 和 redux-saga 的数据流框架,它提供了以下几个核心概念:
-
Model(模型): 用于描述数据、状态和副作用的管理。
-
State(状态): 应用中的数据,存储在每个 Model 中。
-
Reducer(同步处理): 用来同步更新 Model 中的 state。
-
Effect(副作用处理): 用于处理异步操作,通常与
redux-saga
配合使用。 -
Dispatch(派发): 用于触发 Action,更新状态或执行副作用。
-
Connect(连接): 将组件与 Dva 的状态(State)和方法(Dispatch)进行绑定。
1.1. 基本架构
Dva.js 提供了以下三大核心组成部分:
-
Model:用于定义应用状态、同步操作(reducer)和异步操作(effect)。
-
Store:类似于 Redux 中的 store,存储了应用的状态和处理函数。
-
Router:使用 React Router 进行页面导航。
2. 安装 Dva.js
首先,你需要有一个 React 项目。如果没有,请使用 create-react-app
创建一个新项目。
npx create-react-app my-dva-app
cd my-dva-app
npm install dva
3. Dva.js API
Dva.js 提供了一些常用的 API 来初始化应用、定义模型、注册路由等。
3.1. 初始化应用 (dva()
)
通过 dva()
函数来初始化一个 Dva 应用,它是应用的入口。
import dva from 'dva';
// 初始化应用
const app = dva();
3.2. 定义 Model
Dva 中的 Model 用于管理数据和副作用。每个 Model 包含以下几个部分:
-
namespace: 模型的命名空间(全局唯一)。
-
state: 模型的初始状态。
-
reducers: 用来更新状态的同步方法。
-
effects: 用来处理副作用(如异步请求)的函数。
3.2.1. 示例:定义一个简单的 Model
// 定义一个 Model
app.model({
namespace: 'counter',
state: {
count: 0
},
reducers: {
// 更新 state
add(state) {
return { ...state, count: state.count + 1 };
},
reduce(state) {
return { ...state, count: state.count - 1 };
},
},
effects: {
// 异步操作
*asyncAdd(action, { put }) {
yield new Promise(resolve => setTimeout(resolve, 1000)); // 模拟延时
yield put({ type: 'add' });
}
}
});
3.3. 路由配置 (app.router
)
在 Dva.js 中,你需要使用 app.router()
来定义应用的路由,通常结合 React Router 使用。
import React from 'react';
import { Router, Route, Switch } from 'dva/router';
app.router(({ history }) => (
<Router history={history}>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/about" component={About} />
</Switch>
</Router>
));
3.4. 启动应用 (app.start
)
在所有的模型定义和路由配置完成后,使用 app.start()
启动应用。
app.start('#root'); // 挂载到页面中的 #root 元素
4. Dva.js 语法与用法
4.1. model
定义
4.1.1. namespace(命名空间)
每个 Model 必须有一个唯一的命名空间,通常与模型功能相关,如 counter
、user
等。
4.1.2. state(状态)
state
用于存储模型的数据。例如,计数器的 count
。
4.1.3. reducers(同步操作)
reducers
用于同步更新 state
,通过 type
来指定哪个 reducer 进行处理。
reducers: {
add(state) {
return { ...state, count: state.count + 1 };
},
reduce(state) {
return { ...state, count: state.count - 1 };
}
}
4.1.4. effects(副作用)
effects
用于处理异步操作,可以通过 call
来调用异步操作,put
来派发 Action 更新 state
。
effects: {
*asyncAdd(action, { call, put }) {
yield call(delay, 1000); // 模拟延时
yield put({ type: 'add' });
}
}
4.1.5. subscriptions(订阅)
subscriptions
用于监听路由变化或其他事件,并做出反应。通常用于页面加载时获取数据。
subscriptions: {
setup({ dispatch, history }) {
return history.listen(({ pathname }) => {
if (pathname === '/') {
dispatch({ type: 'fetchData' });
}
});
}
}
4.2. connect
(连接)
通过 connect
将 Redux store 中的 state
和 dispatch
映射到组件的 props
中。
import { connect } from 'dva';
const Counter = ({ count, dispatch }) => (
<div>
<h1>Count: {count}</h1>
<button onClick={() => dispatch({ type: 'counter/add' })}>+</button>
<button onClick={() => dispatch({ type: 'counter/reduce' })}>-</button>
</div>
);
export default connect(({ counter }) => ({
count: counter.count
}))(Counter);
4.3. Effects 与 redux-saga
Dva.js 内置了 redux-saga
,用于处理副作用(如异步请求、定时器等)。effects
中的每个函数都是一个 Generator 函数。
effects: {
*fetchData(action, { call, put }) {
const data = yield call(fetchDataFromAPI); // 异步请求
yield put({ type: 'saveData', payload: data }); // 更新 state
}
}
4.4. 生命周期
Dva.js 有多个生命周期钩子,供开发者处理不同的事件。
-
onEffect
:在每次调用effects
前触发。 -
onReducer
:在每次调用reducer
前触发。
4.5. 状态的派发和监听
Dva.js 使用 dispatch
来触发 action,dispatch
可以通过 type
指定哪个 action 被触发。
// 同步更新状态
dispatch({ type: 'counter/add' });
// 异步操作
dispatch({ type: 'counter/asyncAdd' });
你可以通过 connect
来获取应用的状态,并在组件中使用这些状态。
5. 示例:完整的 Dva.js 应用
import React from 'react';
import dva from 'dva';
import { connect } from 'dva';
// 初始化应用
const app = dva();
// 定义 Model
app.model({
namespace: 'counter',
state: { count: 0 },
reducers: {
add(state) {
return { ...state, count: state.count + 1 };
},
reduce(state) {
return { ...state, count: state.count - 1 };
},
},
effects: {
*asyncAdd(action, { call, put }) {
yield new Promise(resolve => setTimeout(resolve, 1000)); // 模拟异步操作
yield put({ type: 'add' });
},
},
});
// 定义组件
const Counter = ({ count, dispatch }) => (
<div>
<h1>Count: {count}</h1>
<button onClick={() => dispatch({ type: 'counter/add' })}>+</button>
<button onClick={() => dispatch({ type: 'counter/reduce' })}>-</button>
<button onClick={() => dispatch({ type: 'counter/asyncAdd' })}>Async +</button>
</div>
);
// 使用 connect 连接状态
const ConnectedCounter = connect(({ counter }) => ({
count: counter.count,
}))(Counter);
// 配置路由
app.router(() => <ConnectedCounter />);
// 启动应用
app.start('#root');
总结
Dva.js 是一个强大的框架,基于 Redux 和 redux-saga 实现了简洁且高效的状态管理方案。它通过 Model 来组织
状态、异步操作和副作用,使得复杂的应用逻辑更容易理解和维护。
-
Model 定义了应用的状态和操作。
-
Effect 用于处理异步操作和副作用。
-
Reducer 用于同步更新状态。
-
Dispatch 用于触发操作和状态变化。
希望这份文档能帮助你更好地理解和使用 Dva.js!如果有任何问题,随时联系我。