欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程资源 > 编程问答 >内容正文

编程问答

react 组件怎么公用-凯发k8官方网

发布时间:2024/10/14 编程问答 13 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 react 组件怎么公用_react、redux与复杂业务组件的复用 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

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)

}

总结

以上是凯发k8官方网为你收集整理的react 组件怎么公用_react、redux与复杂业务组件的复用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

网站地图