7.3 KiB
| name | description |
|---|---|
| jjb-connect | 定义 JJB 命名空间与视图连接规范。在使用 Connect 装饰器、defineNamespace、injectActionProps 或 resetModelState 时使用。 |
接口与数据层规范
命名空间与视图连接
Connect 是 @cqsjjb/jjb-dva-runtime 提供的高阶组件(HOC),用于将 Dva 模型(Model)与 React 组件连接。它支持自动注入模型 state、工具方法,以及(可选的)请求 Action,简化了组件与数据层的交互。
命名空间定义规范
-
集中定义:命名空间必须集中在
src/enumerate/namespace/index.js中定义 -
定义方式:使用
defineNamespace函数定义命名空间常量 -
命名规则:命名空间常量对应
src/api/<namespace>/index.js文件
// src/enumerate/namespace/index.js
import { defineNamespace } from '@cqsjjb/jjb-dva-runtime';
// 这里 user 指的是 src/api/user/index.js
export const NS_USER = defineNamespace('user');
// 这里 order 指的是 src/api/order/index.js
export const NS_ORDER = defineNamespace('order');
// 这里 examList 指的是 src/api/examList/index.js
export const NS_EXAM_LIST = defineNamespace('examList');
请求声明规范
-
文件位置:每个命名空间常量对应一个
src/api/<namespace>/index.js文件 -
声明方式:使用
declareRequest声明接口请求(具体用法参考02-接口定义规范)
// src/api/user/index.js
import { declareRequest } from '@cqsjjb/jjb-dva-runtime';
// 获取用户信息
export const fetchUserAction = declareRequest(
'loading',
'Get > /api/user/{id}',
'userInfo: {} | res.data || {}'
);
// 新增用户(使用 @ 标记)
export const addUserAction = declareRequest(
'confirmLoading',
'Post > @/api/user'
);
Connect API 说明
-
函数签名:
Connect(models, injectActionProps?) -
参数说明:
参数 类型 必填 说明 models Namespace[] 是 命名空间数组,必须从 src/enumerate/namespace引入injectActionProps boolean 否 是否自动注入 action 方法,默认为 false -
injectActionProps 参数说明:
-
false(默认):只能使用dispatchModelAction(namespace, effectAction, payload)手动调用 -
true:所有declareRequest定义的请求会自动注入到组件 props 中,可直接调用
-
注入的 Props
-
State 注入:
-
props.user→ 对应NS_USER模型 -
props.order→ 对应NS_ORDER模型 -
每个命名空间对应一个 props 属性,包含该模型的所有 state(数据字段和 Loading 状态)
-
-
工具方法(始终存在):
-
models:所有连接的模型 -
getModelState(namespace, name):获取模型状态 -
resetModelState(namespace, state):重置模型状态 -
dispatchModelAction(namespace, effectAction, payload?):手动调用 Action -
dispatch(type, payload?):Dva dispatch 方法
-
-
Action 方法(当
injectActionProps = true时才存在):-
例如
declareRequest定义的fetchUserAction会在组件 props 中直接可用 -
Action 方法返回 Promise,使用时需要通过
success字段判断接口是否成功:this.props.xxxAction().then(res => { // 必须通过 success 判断这个接口是否成功 if (res.success) { // 接口成功后的处理逻辑 } }); -
注意:如果接口失败了,不需要手动抛出接口异常错误,http 内部模块已自动拦截并提示错误
-
使用方式
方式一:默认模式(injectActionProps = false) - 不推荐
说明:以下示例仅用于对比理解两种方式的区别,实际开发中请使用推荐的方式二。
此时不会自动注入 Action,需要手动调用 dispatchModelAction:
import React, { useEffect } from 'react';
import { Connect } from '@cqsjjb/jjb-dva-runtime';
import { NS_USER } from '~/enumerate/namespace';
function UserProfile({ user, dispatchModelAction }) {
useEffect(() => {
dispatchModelAction(NS_USER, 'fetchUserAction', { id: 1 });
}, []);
console.log(user?.loading);
console.log(user?.confirmLoading);
return <div>{user.userInfo?.name}</div>;
}
// 注意这里第二个参数没有传(默认为 false)
export default Connect([NS_USER])(UserProfile);
方式二:自动注入 Action(injectActionProps = true) - 推荐
当 injectActionProps = true 时,模型中通过 declareRequest 声明的请求会自动注入到组件 props 中,使用时无需 dispatchModelAction,可以直接调用:
import React, { useEffect } from 'react';
import { Connect } from '@cqsjjb/jjb-dva-runtime';
import { NS_USER } from '~/enumerate/namespace';
function UserProfile({ user, fetchUserAction }) {
useEffect(() => {
fetchUserAction({ id: 1 });
}, []);
console.log(user?.loading);
console.log(user?.confirmLoading);
return <div>{user.userInfo?.name}</div>;
}
// 第二个参数传 true,启用 Action 自动注入到 props
export default Connect([NS_USER], true)(UserProfile);
类组件装饰器语法
如果要连接 class 类组件,使用装饰器语法:
import React, { Component } from 'react';
import { Connect } from '@cqsjjb/jjb-dva-runtime';
import { NS_USER } from '~/enumerate/namespace';
@Connect([NS_USER], true)
class UserProfile extends Component {
componentDidMount() {
this.props.fetchUserAction({ id: 1 });
}
render() {
const { user } = this.props;
return <div>{user.userInfo?.name}</div>;
}
}
export default UserProfile;
多个模型连接示例
import React, { useEffect } from 'react';
import { Connect } from '@cqsjjb/jjb-dva-runtime';
import { NS_USER, NS_ORDER } from '~/enumerate/namespace';
function Dashboard({ user, order, fetchUserAction, fetchOrdersAction }) {
useEffect(() => {
fetchUserAction({ id: 1 });
fetchOrdersAction();
}, []);
return (
<div>
<h3>{user?.userInfo?.name}</h3>
<ul>
{order.list?.map(o => (
<li key={o.id}>{o.title}</li>
))}
</ul>
</div>
);
}
export default Connect([NS_USER, NS_ORDER], true)(Dashboard);
重置状态示例
import { useEffect } from 'react';
import { Connect } from '@cqsjjb/jjb-dva-runtime';
import { NS_USER } from '~/enumerate/namespace';
function UserProfile({ user, fetchUserAction, resetModelState }) {
useEffect(() => {
fetchUserAction({ id: 1 });
return () => {
// 组件销毁时重置状态
resetModelState(NS_USER, {
loading: false,
userInfo: {}
});
};
}, []);
return <div>{user.userInfo?.name}</div>;
}
export default Connect([NS_USER], true)(UserProfile);
使用规范总结
-
命名空间必须集中在
src/enumerate/namespace/index.js中定义,使用defineNamespace函数 -
请求声明必须放在
src/api/<namespace>/index.js中,使用declareRequest -
Connect负责把 state、action 方法注入到组件 -
如果
injectActionProps = true,state、action 自动注入到组件 props,免去手动处理 -
禁止行为:禁止在页面内使用
useState管理本应由declareRequest处理的接口数据或 Loading 状态