共计 2186 个字符,预计需要花费 6 分钟才能阅读完成。
基于 redux 和 react-redux。仓库地址:https://github.com/foca-js/foca
理念
TS First,无 TS 不编程!
个性
- 模块化开发
- 专一 typescript 极致体验
- 模型主动注册,导出即可应用
- 内置 immer 疾速解决数据
- 智能追踪异步函数的执行状态
- 模型反对公有办法
- 可定制的多引擎数据长久化
- 数据隔离,容许同类状态库并存
架构图
在线试玩
CodeSandBox
应用
定义模型
// 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);
心愿能成为你下一个我的项目的状态治理计划!喜爱就先 star 一下吧。
仓库地址:https://github.com/foca-js/foca
正文完