Natural Pleistocene Monsters

    concent-test
    TypeScript icon, indicating that this package has built-in type declarations

    2.5.9 • Public • Published

    English | 简体中文

    ⚡️ State management that tailored for react, it is simple, predictable, progressive and efficient.

    🐮Introduction

    Concent is an amazing state management tool, supported by a healthy middleware ecosystem and excellent devtools. It is a predictable, zero-invasive, progressive, high-performance react development framework!

    Concent encourages simplicity. It saves you the hassle of creating boilerplate code and gives powerful tools with a moderate learning curve, suitable for both experienced and inexperienced developers alike.

    Features

    💻 Playground

    Templates

    A best practise project(git) building by concent & typescript.

    $ git clone https://github.com/tnfe/concent-pro        (dev with webpack)
    $ git clone https://github.com/tnfe/vite-concent-pro   (dev with vite)

    Install by npx command

    $ npx create-react-app my-app --template concent-ts

    or clone its source code by git command

    $ git clone https://github.com/concentjs/cra-project-concent-ts

    Key features snippet

    Online case

    👨🏽‍Docs

    Visit official website https://concentjs.github.io/concent-doc to learn more.

    📦Quick start

    Make sure you have installed nodejs

    Install

    $ npm i --save concent

    or yarn command

    $ yarn add concent

    Minimal example

    See how easy it is to use concent to manage react state.

    import { run, register, useConcent } from 'concent';
    
    // 1️⃣ Configure models
    run({
      counter: {// declare a moudle named 'counter'
        state: { num: 1, numBig: 100 }, // define state
      },
      // you can also put another module here.
    });
    
    // 2️⃣  Now the react component can work with concent
    @register('counter') // 👈 decorate your component with register
    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'); // 👈 call useConcent hook in fn component
      const inc = ()=> setState({num: state.num + 1});
      return <button onClick={inc}>{state.num}</button>
    }

    Complete example

    Move logic to reducer and define computed,watch,lifecycle
    try edit this demo👉better js demo👉better ts demo

    import { run, register, useConcent, 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) => {
            // hate string literal? see https://codesandbox.io/s/combine-reducers-better-7u3t9
            await ac.dispatch("add"); 
            await ac.dispatch("addBig");
          }
        },
        watch: {
          numChange: defWatch(({ num }, o) => console.log(`from ${o.num} to ${num}`), {immediate:true}),
          numChangeWithoutImmediate: ({ num }, o) => console.log(`from ${o.num} to ${num}`),
        },
        lifecycle: {
          // loaded: (dispatch) => dispatch("initState"), // [optional] triggered when module loaded
          // initState: async (moduleState) => {/** async logic */ return{num:666}}, // [optional] allow user load state async
          // initStateDone: (dispatch) => dispatch("addSmallAndBig"), // [optional] call any reducer fn after initState done
          mounted: (dispatch) => dispatch("initState"), // [optional] triggered when the first ins of counter module mounted
          willUnmount: (dispatch) => dispatch("initState") // [optional] triggered when the last ins of counter module unmount
        }
      }
    });
    
    @register("counter")
    class DemoCls extends React.Component {
      render() {
        // mr is short of moduleReducer, now you can call counter module's all 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>;
    }

    🎲Eco-lib examples

    Use with react router

    Details see here react-router-concent,expose history,you can call it anywhere in your app to enjoy the imperative navigation jump.

    react-router-concent online demo

    Use with redux-dev-tool

    Details see here concent-plugin-redux-devtool,track your state changing history。 redux-dev-tool

    Use with plugin-loading

    Details see here concent-plugin-loading,control all your reducer function's loading status easily。

    concent-plugin-loading online demo


    🐚Who is using it


    tcb-admin

    wink

    Communication

    QQ-qroup-qr-code

    👅License

    concent is released under the MIT License. http://www.opensource.org/licenses/mit-license

    Install

    npm i concent-test

    DownloadsWeekly Downloads

    205

    Version

    2.5.9

    License

    MIT

    Unpacked Size

    2.17 MB

    Total Files

    384

    Last publish

    Collaborators

    • fantasticsoul