基于 redux 和 react-redux。仓库地址:https://github.com/foca-js/foca
理念
TS First,无TS不编程!
个性
- 模块化开发
- 专一 typescript 极致体验
- 模型主动注册,导出即可应用
- 内置 immer 疾速解决数据
- 智能追踪异步函数的执行状态
- 模型反对公有办法
- 可定制的多引擎数据长久化
- 数据隔离,容许同类状态库并存
架构图
在线试玩
CodeSandBox
应用
定义模型
// File: counterModel.tsimport { 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