juejin-cn/open-source

【自荐】简单易学、功能强大的react状态管理方案:Concent

fantasticsoul opened this issue · 4 comments

项目简介

功能与特点

  • 自动注入渲染上下文
  • 依托于运行时的依赖收集(包含状态与计算)做到精确更新
  • 统一类组件和函数组件逻辑复用方式(包括生命周期函数)
  • 支持可选的组合api
  • 支持模块化开发(state、reducer、computed、watch、lifecycle)
  • 高效的renderKey机制
  • 同时支持中心话和去中心化配置模块
  • 支持动态模块配置
  • 支持模块克隆
  • 支持reducer组合调用
  • 内置事件系统
  • 支持扩展中间件与插件
  • 支持React Devtools
  • 支持热加载
  • 兼容redux生态相关库
  • 支持 nextjs ssr
  • 支持react-native
  • 友好且完善的typescript支持

快速开始

使用npm安装concent

$ npm i --save concent

简单示例

import { run } from 'concent';
import { register, useConcent } from 'concent';

run({
  counter: {// declare a moudle named 'counter'
    state: { num: 1, numBig: 100 }, // define state
  },
  // you can also put another module here.
});

@register('counter')
class DemoCls extends React.Component{
  // commit state to store and broadcast to other refs which also belong to counter module
  inc = ()=> this.setState({num: this.state.num + 1})
  render(){
    // here if read num, it means current ins render dep keys is ['num']
    return <button onClick={this.inc}>{this.state.num}</button>
  }
}

function DemoFn(){
  const { state, setState } = useConcent('counter');
  const inc = ()=> setState({num: state.num + 1});
  return <button onClick={inc}>{state.num}</button>
}

export default function App(){
  return (
    <div>
      <ClsComp />
      <FnComp />
    </div>
  );
}

完整示例

  • Move logic to reducer and define computedwatchlifecycle

try edit this demo、 👉better js demo、👉better ts demo

import { run, defWatch } from 'concent';

run({
  counter: {
    state: { num: 1, numBig: 100 },
    computed: {
      numx2: ({ num }) => num * 2, // only num changed will trigger this fn
      numx2plusBig: ({ numBig }, o, f) => f.cuVal.numx2 + numBig // reuse computed reslult
    },
    reducer: {
      initState: () => ({ num: 8, numBig: 800 }),
      add: (payload, moduleState, actionCtx) => ({ num: moduleState.num + 1 }),
      addBig: (p, m, ac) => ({ numBig: m.numBig + 100 }),
      asyncAdd: async (p, m, ac) => {
        await delay(1000);
        return { num: m.num + 1 };
      },
      addSmallAndBig: async (p, m, ac) => {
        await ac.dispatch("add"); // hate string literal? see https://codesandbox.io/s/combine-reducers-better-7u3t9
        await ac.dispatch("addBig");
      }
    },
    watch: {
      numChange: defWatch(({ num }, o) => console.log(`from ${o.num} to ${num}`), {immediate:true})
    },
    lifecycle: {
      // loaded: (dispatch) => dispatch("initState"), // when module loaded
      mounted: (dispatch) => dispatch("initState"), // when any first ins of counter module mounted will trigger this
      willUnmount: (dispatch) => dispatch("initState") // when last ins of counter module unmount will trigger this
    }
  }
});

@register("counter")
class DemoCls extends React.Component {
  render() {
    // mr is short of moduleReducer, now you call all counter module reducer fns by mr
    return <button onClick={this.ctx.mr.add}>{this.state.num}</button>;
  }
}

function DemoFn() {
  const { moduleComputed, mr } = useConcent("counter");
  return <button onClick={mr.add}>numx2plusBig: {moduleComputed.numx2plusBig}</button>;
}

暂时不考虑有明显加群之类的项目哦,如果可以改一下话,后期会考虑在专题进行收录~

暂时不考虑有明显加群之类的项目哦,如果可以改一下话,后期会考虑在专题进行收录~

感谢提示,已删掉二维码

你好,官方回复呢????

我们会在合适的期刊中审核并收录,整个开源计划正在逐渐走向系统化,流程化,请再多一点耐心哦❤️