流畅的 react 状态管理库,基于redux和react-redux。简洁、极致、高效。
- 模块化开发,导出即可使用
- 专注 TS 极致体验,超强的类型自动推导
- 内置 immer 响应式修改数据
- 支持计算属性,自动收集依赖,可传参数
- 自动管理异步函数的 loading 状态
- 可定制的多引擎数据持久化
- 支持局部模型,用完即扔
- 支持私有方法
- Browser
- React Native
- Taro
- Electron
# npm
npm install foca
# yarn
yarn add foca
# pnpm
pnpm add foca
import { store } from 'foca';
store.init();
import { defineModel } from 'foca';
const initialState: { count: number } = { count: 0 };
export const counterModel = defineModel('counter', {
initialState,
reducers: {
// 支持无限参数
plus(state, value: number, times: number = 1) {
state.count += value * times;
},
minus(state, value: number) {
return { count: state.count - value };
},
},
});
export const counterModel = defineModel('counter', {
initialState,
// 自动收集依赖
computed: {
filled() {
return Array(this.state.count)
.fill('')
.map((_, index) => index)
.map((item) => item * 2);
},
},
});
export const counterModel = defineModel('counter', {
initialState,
reducers: {
increment(state) {
state.count += 1;
},
},
methods: {
async incrementAsync() {
await this._sleep(100);
this.increment();
// 也可直接修改状态而不通过reducers,仅在内部使用
this.setState({ count: this.state.count + 1 });
this.setState((state) => {
state.count += 1;
});
return 'OK';
},
// 私有方法,外部使用时不会提示该方法
_sleep(duration: number) {
return new Promise((resolve) => {
setTimeout(resolve, duration);
});
},
},
});
export const counterModel = defineModel('counter', {
initialState,
events: {
// 模型初始化
onInit() {
console.log(this.state);
},
// 模型数据变更
onChange(prevState, nextState) {},
},
});
import { FC, useEffect } from 'react';
import { useModel, useLoading } from 'foca';
import { counterModel } from './counterModel';
const App: FC = () => {
const count = useModel(counterModel, (state) => state.count);
const loading = useLoading(counterModel.incrementAsync);
useEffect(() => {
counterModel.incrementAsync();
}, []);
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.incrementAsync();
}
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.incrementAsync),
};
};
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 | 当下最流行的请求库 | |
foca-axios | axios++ 支持 节流、缓存、重试 | |
foca-openapi | 使用openapi文档生成请求服务 |
仓库 | 版本 | 描述 | 平台 |
---|---|---|---|
react-native-async-storage | React-Native 持久化引擎 | RN | |
foca-taro-storage | Taro 持久化引擎 | Taro | |
localforage | 浏览器端持久化引擎,支持 IndexedDB, WebSQL | Web | |
foca-electron-storage | Electron 持久化引擎 | Electron | |
foca-mmkv-storage | 基于 mmkv 的持久化引擎 | RN | |
foca-cookie-storage | Cookie 持久化引擎 | Web |
仓库 | 版本 | 描述 | 平台 |
---|---|---|---|
@redux-devtools/extension | 浏览器日志插件 | Web, RN | |
react-native-debugger | 日志应用程序 | RN | |
redux-logger | 控制台输出日志 | Web, RN, Taro |
答:需要在文件 tsconfig.json 中开启"strict": true
或者"noImplicitThis": true
更多答案请查看文档
开源不易,升级维护框架和解决各种 issue 需要十分多的精力和时间。希望能得到你的支持,让项目处于良性发展的状态。捐赠地址:二维码
arcsin1 |
xiongxliu |