Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/ concent Public
forked from heluxjs/helux

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

License

Notifications You must be signed in to change notification settings

Taisho/concent

Repository files navigation

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

Communication

QQ-qroup-qr-code

👅License

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

About

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

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%

AltStyle によって変換されたページ (->オリジナル) /