前言
组件隔离适用范围 同一个页面引用多个相同的自定义公共组件(该类组件拥有自己的Redux)并且这些组件之间有交互。 案例背景 在一个页面中存在两个相同的公共组件(A),在页面处理中,对A组件进行操作,有一些重要的数据被存入到A组件的对应的Redux中。 如果该页面只存在一个A组件,不管进行如何的操作,数据都是一份。但是如果该页面中存在多个A组件,在对第一个A组件进行数据处理之后,数据存入到Rudex中。此时在对另一个A组件进行相同的操作步骤,但是存入的数据和第一个A组件的存储在Redux中的数据有差别,此时在第二个A组件的操作就会影响第一个A组件的数据。
原因:由于页面中引用的是相同的组件,在进行数据处理的时候,都会存在到Redux中,而该组件的Redux在内存中只是保存了一份。
这就类似于如下操作
let ob1 = new Object();======类似===>定义了一个组件 ob1.name = 'haha';=========类似====>进行数据处理的时候,将组件的一些数据存入到对应的Redux中。 ==============华丽的分割线================== ob1.name ="hehe";=========类似=====>此处类似于第二个组件进行相同的操作,将对应的Redux中的数据进行了变化,该变化会影响到上面的代码。 复制代码
利用Provider
在需要处理组件隔离的页面中引用如下代码
import { Provider } from 'react-redux';[Provider属于react-redux](https://github.com/reactjs/react-redux/blob/master/docs/api.md#provider-store) import { createStore } from 'redux' ===>用于生成总的Store import { Router, browserHistory } from 'react-router'; 复制代码
在组件的constructor中进行变量的初始化
export default class PersonComponent extends Component { constructor(props,context){ super(props,context); this.store1 = createStore(reducer); ===>此处的reducer是你自己的页面的reducer } render(){ //.... } } 复制代码
关于createStore 处理需要隔离的组件
render(){ <div> <A/> <Provider store={this.store1}> ===>此处的store1是根据你页面的reducer构建的 <A/> ==>此处为需要隔离的组件 </Provider> </div> } 复制代码
基于如上操作,第二个A组件被成功的隔离出整个Store树之外(换句话说,该A组件自己定义了一套Store)
但是,组件隔离是为了在操作之后,拥有相同的Redux的组件在进行相同的操作步骤之后,互相不被影响。所以,需要根据刚才在第二步构建的Store1来进行对应的action的dispatch.
this.store1.getState().xxx ===>此处的xxx是在rootReducer.js中combineReducers引用的A组件的Redux的同名State(Note:此处也有对应的方法起一个与Redux不同的名字,自行百度吧) 上面是用于获取A组件中state数据的, this.store1.dispatch(yyy(param)) ===>此处的yyy是在A组件的ActionCreator (该用法请参考Redux官网) 复制代码
上面一行代码用户发送一个action
利用第三方库multireducer
multireducer该库的主要目的就是为了实现组件隔离。
对应的github地址 核心思想:A utility to wrap many copies of a single Redux reducer into a single key-based reducer.
项目中引用multireducer
npm install --save multireducer 复制代码
在组件定义处处理
引用connectMultireducer
import {connectMultireducer} from 'multireducer'; 复制代码
组件与Redux进行关联
@connectMultireducer( (key, state) => ({count: state.multireducer[key].count}), {increment} ) 复制代码
此处的处理方式和华南城项目中@connect的用法类似 主要的区别在与该方法中第二个参数为需要隔离组件的redux.js
在组件调用除处理
<A multireducerKey="1" /> <A multireducerKey="2" /> <A multireducerKey="3" /> 复制代码
此处在一个页面中引用了三个相同的组件,有一个multireducerKey是必须的,用于区分组件。(这和React在处理List等拥有相同数据结构的组件的时候,需要一个key是相同的道理)
处理Rudecer
在进行combineReducers处,需要指出刚才multireducerKey对应的value是指的什么
export default combineReducers({ routing: routerReducer, reduxAsyncConnect, multireducer: multireducer({ 1: XXX, 2: XXX, 3: XXX }) }); 复制代码
此处的格式是固定的,XXX代表需要进行隔离处理的组件的Redux,对应的1,2,3就是在步骤3处multireducerKey的值,(note:说的是格式固定,但是其中的参数是可以根据自己的情况进行变化的)
基于如上的4步操作就可以将A组件进行组件隔离操作了。 原理解释
采用此处的处理方式与第一种处理方式相比,被隔离的组件没有脱离整个Store树,而是根据multireducerKey来判断用户当前操作发送的action是来自哪个一个,然后根据multireducerKey进行对应的数据操作处理。