Get Started ➜
npm versiondownloadscommit activitylicense:MITfollowersconcent star

What can Concent offer you

极简核心api

run载入模块配置,register注册类组件,useConcent注册函数组件。

0入侵成本接入

无根Provider包裹,注册后的组件setState即可更新store。

贴心模块配置

模块提供state、reducer、watch、computed和init 5个选项,支持按需定义,覆盖所有业务场景。

数据消费粒度灵活

支持组件跨多个模块消费数据,定义key级别的变更依赖。

渐进式

除setState之外,还支持dispatch、invoke提交数据变更,同时让ui视图与业务逻辑彻底解耦。

组件能力增强

支持实例级别computed、watch定义;支持组件emit&on;支持setup特性实现composition api.

高度一致的编程体验

hoc、render props和hook 3种方式定义的组件均享有一致的api调用体验,相互切换代价为0。

渲染性能出众

启用Proxy在运行时动态收集每一个组件的最新依赖列表,保证最小粒度更新,同时内置renderKey、lazyDispatch、delayBroadcast等高级特性满足更复杂的更新场景。

干净的dom层级

对于class组件,默认采用反向继承策略,让react dom树的层级结构保持简洁与干净。

扩展中间件与插件

支持定义中间件拦截所有的数据变更提交记录做额外处理,也支持自定义插件接收运行时的各种信号,增强concent能力。

去中心化配置模块

支持任意地方调用configure接口动态配置模块,方便就近配置模块,且能够独立打包组件发布npm。

模块克隆

支持对已定义模块进行克隆运行时是完全独立的新模块,满足抽象工厂函数等高维度抽象。


How to install

npm install concent --save

//or 

yarn add concent

Key features preview

❤️Enjoy composition api with 🔥dependency collection🔥
import { run, useConcent } from "concent";

run();// 启动concent
const setup = ctx => {
  const { initState, computed, watch, setState } = ctx;
  // 初始化实例状态
  initState({ count: 0 });
  // 定义计算函数,这里的依赖是count,仅当count变化,触发此函数重新计算
  computed("doubleCount", n => n.count * 2);
  // 定义观察函数,这里的依赖是count,仅当count变化,会弹此提示
  watch("count", (n, o) => alert(`from ${o.count} to ${n.count}`));
  // 打包方法返回,将被收集到settings里
  return {
    inc: () => setState({ count: ctx.state.count + 1 }),
    dec: () => setState({ count: ctx.state.count - 1 })
  };
};

function Counter(){
  // 这些是从实例上下文里解构出来的属性
  const { state, refComputed, settings } = useConcent({ setup });
  return (
    <>
      <h1>{state.count}</h1>
      <h1>{refComputed.doubleCount}</h1>
      <button onClick={settings.inc}>inc</button>
      <button onClick={settings.dec}>dec</button>
    </>
  );
}

❤️Easily share state and reuse logic between class and function
import { run, useConcent } from "concent";

const delay = (ms = 1000) => new Promise(r => setTimeout(r, ms));

run({// 载入模块配置启动concent  counter: {
    state: { count: 0 },// 【必需】,定义模块状态
    reducer: {
      async complexUpdate(p, m, ac) {
        await delay();
        await ac.setState({ count: m.count + 10 });
        await delay();
        return { count: m.count + 10 };
      },
      simpleUpdate(p, m) {
        return { count: m.count - 100 };
      }
    },
    computed: {// 【可选】,定义模块计算
      doubleCount: n => n.count * 2,
      quadrupleCount: (n, o, f) => f.cuVal.doubleCount * 2,
    },
    watch: {// 【可选】,定义模块观察
      count: (n, o) => alert(`from ${o.count} to ${n.count}`)
    }
  }
});

const setup = ctx => {
  return {
    inc: () => ctx.setState({ count: ctx.state.count + 1 }),
    dec: () => ctx.setState({ count: ctx.state.count - 1 })
  };
};

function Counter() {
  const { state, moduleComputed, moduleReducer, settings } = 
    useConcent({ setup, module: "counter" });
  return <div> ui ... </div>
}

@register({ setup, module: "counter" })
class ClassCounter extends React.Component{
  render(){
    const { state, moduleComputed, moduleReducer, settings } = this.ctx;
    return <div> ui ... </div>
  }
}



Experience standard js concent project
Experience standard ts concent projectExplore more