npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

foca

v3.2.0

Published

流畅的React状态管理库

Downloads

215

Readme

FOCA

流畅的 react 状态管理库,基于reduxreact-redux。简洁、极致、高效。

npm peer react version npm peer typescript version GitHub Workflow Status (branch) Codecov npm npm npm bundle size (version) License Code Style

mind map

特性

  • 模块化开发,导出即可使用
  • 专注 TS 极致体验,100%类型提示
  • 内置 immer 响应式修改数据
  • 支持 computed 计算属性,自动收集依赖,可传参数
  • 支持私有方法
  • 自动管理异步函数的 loading 状态
  • 可定制的多引擎数据持久化
  • 使用ES5语法,超强兼容性

使用环境

  • Browser
  • React Native
  • Taro
  • Electron

安装

# npm
npm install foca
# yarn
yarn add foca
# pnpm
pnpm add foca

初始化

import { store } from 'foca';

store.init();

创建模型

reducers 修改数据

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 };
    },
  },
});

computed 计算属性

export const counterModel = defineModel('counter', {
  initialState,
  // 自动收集依赖
  computed: {
    filled() {
      return Array(this.state.count)
        .fill('')
        .map((_, index) => index)
        .map((item) => item * 2);
    },
  },
});

methods 组合逻辑

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);
      });
    },
  },
});

events 事件回调

export const counterModel = defineModel('counter', {
  initialState,
  events: {
    // 模型初始化
    onInit() {
      console.log(this.state);
    },
    // 模型数据变更
    onChange(prevState, nextState) {},
  },
});

使用

在 function 组件中使用

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;

在 class 组件中使用

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://foca.js.org

例子

沙盒在线试玩: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 | npm | 当下最流行的请求库 | | foca-axios | npm | axios 适配器,节流、缓存、重试 |

持久化存储引擎

| 仓库 | 版本 | 描述 | 平台 | | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -------- | | react-native-async-storage | npm | React-Native 持久化引擎 | RN | | foca-taro-storage | npm | Taro 持久化引擎 | Taro | | localforage | npm | 浏览器端持久化引擎,支持 IndexedDB, WebSQL | Web | | foca-electron-storage | npm | Electron 持久化引擎 | Electron | | foca-cookie-storage | npm | Cookie 持久化引擎 | Web |

日志

| 仓库 | 版本 | 描述 | 平台 | | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------- | ------------- | | @redux-devtools/extension | npm | 浏览器日志插件 | Web, RN | | react-native-debugger | npm | 日志应用程序 | RN | | redux-logger | npm | 控制台输出日志 | Web, RN, Taro |

常见疑问

函数里 this 的类型是 any

答:需要在文件 tsconfig.json 中开启"strict": true或者"noImplicitThis": true


更多答案请查看文档

缺陷

捐赠

开源不易,升级维护框架和解决各种 issue 需要十分多的精力和时间。希望能得到你的支持,让项目处于良性发展的状态。捐赠地址:二维码