- 1.前言
- 2.基本用法
- 2.1 providerState:用于往store里面添加数据
- 2.2 injectState用于把store里面的数据传入UI组件
- 2.3 effects 用于更改store里面的数据,进行更新组件
- 2.4 initialState 用于定义初始状态
- 3.在项目中的应用
- 3.1 存储共享数据
- 3.2 #在复杂场景下更新组件
- 4.举个项目中的操作栗子
- 结语
1.前言
单页应用还是需要一个状态管理器,之前尝试过redux,后来觉得它的写法太繁琐了,还需要装各种依赖,弃之,使用一个较为简单的freactal。
2.基本用法
2.1 providerState 用于往store里面添加数据。
providerState({initialState,effects,computed,
})
复制代码
不同于redux,freactal可以设置多个store,所以providerState有一个特性:在某个先加载的组件使用providerState提供了数据,那么后加载的组件使用providerState传入一个空对象,也可以拿到之前存入store里面的数据,比如:
providerState({})
复制代码
可以理解为freactal虽然支持书写多个store,但是数据的来源是唯一的,只是写法上可以书写多个store.js用于区分不同的store,如果你不需要别的store里面的数据,可以使用injectState进行过滤。
2.2 injectState 用于把store里面的数据传入UI组件
injectState(component, key)
复制代码
key用于筛选store里面的数据,再次声明:如果某个先加载的组件使用providerState往store里面添加的数据,那么后加载的组件使用providerState也是可以拿到这些数据的,所以通过injectState进行过滤你所需要的数据,只有过滤后的数据改变,才会触发对应的组件更新。
2.3 effects 用于更改store里面的数据,进行更新组件
const effects = {changeMenu: (effects, args) => mergeIntoState({currentMenu: args})
}
复制代码
- args是外部传入的参数,比如this.props.effects.changeMenu('/record')
- mergeIntoState相当于于reducer,用于更改store里面的数据
2.4 initialState 用于定义初始状态
const initialState = () => ({active: 'hello'
})
复制代码
更多api请查看文档:freactal
3.在项目中的应用
最初接触状态管理容器的时候直接把接口请求中的数据往store里面丢,其实这是没有必要的,而且会让代码的书写变得十分的繁琐,于是认真思考了一下使用状态管理容器的初衷,总结有以下几点:
3.1 存储共享数据
使用react开发通常会把组件细化,当组件的层级比较多,数据一层一层往下传递,书写的体验就会变得十分糟糕,在单页应用中,这个缺点会无限放大。
如果有些数据需要在多个组件中共享,那么请放在store中。这样无论组件的层级有多深,大家都可以使用this.props拿到。
3.2 在复杂场景下更新组件
比如当子孙组件需要更新祖先组件的状态,用于显示一个Modal,那么代码会变成这样: 在祖先组件中定义一个方法:
showModal = (bool) => {this.setState({show: bool});
}
复制代码
方法通过层层传递,传入子孙组件中,调用该方法
this.props.showModal(true)
复制代码
代码变得十分繁琐,也不优雅,不如把这个状态存入store,当store中的数据改变,UI会被更新,兄弟组件之间数据的操作更新UI其实也是同理。
4.举个项目中的操作栗子
定义store.js
import { mergeIntoState } from 'freactal';// active为1是云阅读,2是蜗牛
const initialState = () => ({active: '1',
});const effects = {toggleRadio: (effect, args) => mergeIntoState({active: args})
};export default {initialState,effects
};
复制代码
封装withStore.js
import { provideState, injectState } from 'freactal';
import createLogger from 'freactal-logger';export default (store, keys) => (statefull) => {const middleware = [];if (process.env.NODE_ENV === 'development') {const logger = createLogger({collapsed: true});middleware.push(logger);}return provideState({...store,middleware})(injectState(statefull, keys));
}复制代码
- createLogger是一个logger,可以看到store中数据的修改
UI组件连接store
import store from './store';
import withStore from './withStore';@withStore(store, ['active'])
class Result extends React.Component {}
复制代码
5.结语
react16.3.1已经更新了新的Context API,操作共享数据变得十分方便了,有空可以研究一下,但是它并不能替代状态管理容器,在单页的应用中,复杂的场景下,还是需要它。
原文连接