流畅的 react 状态管理库,基于redux和react-redux。简洁、极致、高效。
- 模块化开发
- 专注 typescript 极致体验
- 模型自动注册,导出即可使用
- 内置 immer 快速处理数据
- 智能追踪异步函数的执行状态
- 模型支持私有方法
- 可定制的多引擎数据持久化
- 数据隔离,允许同类状态库并存
yarn add foca
// File: counterModel.ts
import { defineModel } from 'foca';
const initialState: { count: number } = {
count: 0,
};
// 无须手动注册到store,直接导出到react组件中使用
export const counterModel = defineModel('counter', {
// 初始值,必填属性,其他属性均可选
initialState,
actions: {
// state可自动提示类型 { count: number }
plus(state, value: number, double: boolean = false) {
// 直接修改状态
state.count += value * (double ? 2 : 1);
},
minus(state, value: number) {
// 直接返回新状态
return { count: state.count - value };
},
// 私有方法,只能在模型内部被effect方法调用,外部调用则TS报错(属性不存在)
_clear(state) {
return this.initialState;
},
},
effects: {
// 异步函数,自动追踪执行状态(loading)
async doSomething() {
// 调用私有方法
await this._sleep(100);
// 快速处理状态,对于网络请求的数据十分方便
this.setState({ count: 1 });
this.setState((state) => {
state.count += 1;
});
// 调用action函数处理状态
this.plus(1, true);
// 调用effect函数
return this.commonUtil(1);
},
// 普通函数
commonUtil(x: number) {
return x + 1;
},
// 私有方法,只能在模型内部使用,外部调用则TS报错(属性不存在)
_sleep(duration: number) {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
},
},
hooks: {
// store初始化完成后触发onInit钩子
onInit() {
this.plus(1);
console.log(this.state);
},
},
});
import { FC, useEffect } from 'react';
import { useModel, useLoading } from 'foca';
import { counterModel } from './counterModel';
const App: FC = () => {
// count类型自动提示 number
const { count } = useModel(counterModel);
// 仅effects的异步函数能作为参数传入,其他函数TS自动报错
const loading = useLoading(counterModel.doSomething);
useEffect(() => {
counterModel.doSomething();
}, []);
return (
<div onClick={() => counterModel.plus(1)}>
{count} {loading ? 'Loading...' : null}
</div>
);
};
export default App;
import { Component } from 'react';
import { connect, getLoading } from 'foca';
import { counterModel } from './counterModel';
type Props = ReturnType<typeof mapStateToProps>;
class App extends Component<Props> {
componentDidMount() {
counterModel.doSomething();
}
render() {
const { count, loading } = this.props;
return (
<div onClick={() => counterModel.plus(1)}>
{count} {loading ? 'Loading...' : null}
</div>
);
}
}
const mapStateToProps = () => {
return {
count: counterModel.state.count,
loading: getLoading(counterModel.doSomething),
};
};
export default connect(mapStateToProps)(App);
沙盒在线试玩:https://codesandbox.io/s/foca-demos-e8rh3
React 案例仓库:https://github.com/foca-js/foca-demo-web
RN 案例仓库:https://github.com/foca-js/foca-demo-react-native
Taro 案例仓库:https://github.com/foca-js/foca-demo-taro
仓库 | 版本 | 描述 | 平台 |
---|---|---|---|
axios | 当下最流行的请求库 | React, RN | |
foca-axios | 针对 axios 的增强型适配器 | React, RN | |
foca-miniprogram-axios | 针对 axios 的增强型适配器 | Taro, Remax | |
foca-taro-storage | Taro 持久化引擎 | Taro | |
rn-async-storage | React-Native 持久化引擎 | RN | |
localForage | 浏览器端持久化引擎 | React | |
redux-logger | 控制台打印 redux 日志 | React, RN Taro, Remax |