react 组件怎么公用-ag凯发k8国际
all state in redux
在上一篇文章【redux的副作用处理与no-reducer开发模式】中,我们介绍了如何使用redux/redux-saga来进行组件的状态共享,以及副作用处理。
在随后的开发中,我们所有的页面,以及业务逻辑组件都使用了这一套开发模式。举一个例子,我们有一个app搜索的autocomplete组件,这个组件会做如下事情:从redux的state中读取用户token。
通过用户的token,请求后台服务,获取这个用户有权限看到的app列表。
将app信息载入组件,根据用户输入返回对应的搜索项。
由于这个组件需要读取存放在redux state中的用户token,并且包含异步请求,将它的状态放入redux中管理,并且使用redux-saga处理异步请求是非常合适的。
组件复用
但是在组件的复用性上,我们遇到一个难题,由于redux本身并不提供模块化功能,我们想要复用使用了redux/redux-saga的组件时:我们需要为这个组件注册一个全局不冲突的reducerkey。
我们需要修改组件所关注的action类型,因为全局会有多个组件实例,如果action类型重复,会引起错误的组件状态改变。
在组件被卸载(umountained)后,由于保存在redux中的state不会被自动销毁,我们需要手动清理组件的app列表信息。
组件被卸载后,reducer继续存在,会轻微的损失一些执行性能。
针对这种情形,我们开发了redux-arena会将redux/redux-saga的代码与react组件导出成一个react高阶组件以供复用:在高阶组件被挂载(mount)时,会自动初始化redux-saga的任务,初始化组件的reducer并在redux维护的state上注册自己的节点。
在高阶组件被卸载(unmout)时,会自动取消redux-saga的任务,销毁组件的reducer并从redux维护的state上删除自己的节点。
提供组件信道机制,组件发送的action默认只能被组件自己的reducer接收。也可以通过配置放弃信道,接收全局的action。
提供vreducerkey机制,redux中如果组件间想共享state信息,需要知道知道真实的节点名称,在可复用的redux组件中很容易引发冲突,redux-arena提供vreducerkey机制保证了state节点真实名称永远不会冲突。vreducerkey在同名时,下层组件会覆盖掉上层组件的vreducerkey信息。
提供单向的(类似flux的 one-way data flow)组件状态和actions的共享方案,下层组件可以通过vreducerkey获取上层组件的state和actions。
与redux-saga深度整合,在redux-saga中也可以选择只发送和接收组件自己的action。
构造可复用的高阶组件(scene)
我们将每一个导出的redux/react绑定的高阶组件称为scene。首先我们要为scene构造actions和reducer,然后使用bundletocomponent,导出高阶组件。
import { bundletocomponent } from "redux-arena/helper";
import * as actions from "./actions";
import state from "./actions";
import reducer from "./reducer";
import componenta from "./componenta";
export default bundletocomponent({
component: componenta,
actions,
state,
reducer
});
现在我们导出的这个组件,就可以和普通的组件一样直接在react中使用了。
需要注意的是,redux-arena增强了redux的store,需要使用createarenastore创建store:
import react from "react";
import reactdom from "react-dom";
import { provider } from "react-redux";
import { createarenastore } from "redux-arena";
import componenta from "./componenta";//上面导出的高阶组件
const store = createarenastore();
const app = document.getelementbyid("app");
reactdom.render(
,
app
);
非常的简单。
通讯隔离
每个scene默认只会接受自己所发送的action,其他scene或者原生redux绑定的action,将会被忽略。
举个例子:
import { bundletocomponent } from "redux-arena/helper";
import * as actions from "./actions";
import reducer from "./reducer";
import componenta from "./componenta";
export const componenta1 = bundletocomponent({
component: componenta,
actions,
reducer
});
export const componenta2 = bundletocomponent({
component: componenta,
actions,
reducer
});
componenta1和componenta2的代码来源都是相同的,但是他们的reducer只会接收自己的scene内部发送的action,其他组件发送的action即使type相同,也会被忽略。
state与actions共享
原生的redux中,如果要实现state的共享,需要为组件注册一个全局唯一的reducerkey,然后使用mapstatetoprops方法,将对应state传入props。
redux-arena使用了vitural reducerkey(vreducerkey),vreducerkey不要求全局唯一,当子组件的vreducerkey与父组件的vreducerkey相同时,子组件的vreducerkey会覆盖掉父组件的vreducerkey的信息。
为scene指定vreducerkey:
import { bundletocomponent } from "redux-arena/helper";
import * as actions from "./actions";
import reducer from "./reducer";
import componenta from "./componenta";
export default bundletocomponent({
component: componenta,
actions,
reducer,
options: {
vreducerkey: "a1"
}
});
和mapstatetoprops相似,子组件使用propspicker取出所需要的state和actions:
import { bundletocomponent } from "redux-arena/helper";
import state from "./state";
import actions from "./actions";
import componentachild from "./componentachild";
export default bundletocomponent({
component: componenta,
state,
actions,
propspicker:(state,actions,allstate,{ a1 })=>({
name: state.name, //scene的state actions, //scene的actions a1name: allstate[a1.reducerkey].name, //componenta的state a1actions: a1.actions //componenta的actions })
});
这样,我们就实现了组件间的state与actions的共享。
需要注意的是,这种共享模式类似flux的one-way data flow,传递方向是单向的,反向的信息传递不能使用state,只能使用action。
如果是兄弟组件间的state共享,需要在这些兄弟组件间的某一个父组件上增加一个数据层,使用这个统一的父组件数据层共享状态。
redux-saga的整合
redux-arena提供了一系列的redux-saga方法实现通讯的隔离,使在redux-saga中可以只接收当前scene所派发的action。
使用setscenestate,可以方便的设置当前scene的state。
import { setscenestate, takelatestsceneaction } from "redux-arena/sagaops";
function * dosomthing({ payload }){
yield* setscenestate({ payload })
}
export function* saga (){
yield takelatestsceneaction("do_something", dosomthing)
}
总结
以上是ag凯发k8国际为你收集整理的react 组件怎么公用_react、redux与复杂业务组件的复用的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 华为交换机导入配置_华为交换机基础配置1
- 下一篇: javascript取随机数_js怎么产