Open source is not easy, thanks for your support ❤ star concent^_^
The preface
Concent is a series of articles designed to help beginners learn and understand Concent’s state management ideas.
While learning and using state management libraries such as Redux and Mbox will make this article easier to understand, anyone who has never used any state management libraries can get up to speed on Concent, a real barrier to learning how to use it and plug it into your React app.
Note that the 0 barriers highlighted above include both learning to use and accessing the application. In order to achieve this, the API must be simple enough. How simple? The React component is written in the same way that newcomers can access state management without having to understand additional overviews, but the React component also retains a higher-level abstraction interface that allows veterans to organize code in a redux fashion.
Come on, show! The key APIS in this tutorial include three top-level apirun, useConcent, register, and an instance context apisetState. Learn to use these four apis and you will already be using Concent as your state management solution.
Hello world
All frameworks start with Hello World, and we’re no exception here. See how simple the Concent version of Hello World is.
Run defines the module
Concent, like Redux, has a global single state tree, which is a common JSON object. However, the key at the first layer is planned as a module name to help users split the state into multiple modules based on business scenarios for easy management.
Here we need to start Concent using the Run interface and load the module configuration, configure a module called Hello, and define its state
import { run } from 'concent';
run({
hello: {
state: { greeting: 'Hello world',}}});Copy the code
Register Registers class components
Once the module is defined, our component needs to consume the module’s state. For class components, use Register
import { register } from 'concent';
@register('hello')
class HelloCls extends React.Component{
state = { greeting: ' ' };
changeGreeting = (e) = > this.setState({greeting: e.target.value})
render(){
return <input value={this.state.greeting} onChange={this.changeGreeting} />}}Copy the code
Concent will inject an instance context CTX to the current component this, which will read data and call modification methods. Concent will also silently replace state and setState on this. This is the foundation for learning how to use and connect to the React application. For starters, if you can write the React component, you already know how to use Concent without any additional learning costs.
this.state === this.ctx.state; // true
this.setState === this.ctx.setState; // true
Copy the code
In the above code, we also declare a class member variable state equal to {greeting: }, because the new greeting is the same name as the module state, the value will be replaced by the module Hello World before the first rendering. In fact, the class member variable state can be left undeclared, just to make sure that deleting the register decorator works. Instead of getting an initial greeting value of undefined.
UseConcent Registers function components
Use the useConcent interface to register the module that the current component belongs to. UseConcent will return the instance context object CTX of the current component, which is equivalent to this. CTX of the above class component.
import { useConcent } from 'concent';
function HelloFn(){
const { state, setState } = useConcent('hello');
const changeGreeting = (e) = > setState({greeting: e.target.value})
return <input value={state.greeting} onChange={changeGreeting} />
}
Copy the code
Rendering component
When we look at the complete code, we see that the top, providerless component is wrapped around the root component, because Concent does not rely on the React Context API for state management. Instead, concent maintains a separate global Context. So it’s very easy to plug and play concent into your existing projects without any additional modifications.
Since both HelloCls and HelloFn components belong to the Hello module, when one of them changes the module state, Concent stores it to the Store and synchronizes it to other instances of the hello module. State sharing is as simple as that.
import ReactDOM from 'react-dom';
import { run } from 'concent';
import { register, useConcent } from 'concent';
run({/ * * * /});
@register('hello')
class HelloCls extends React.Component{/ * * * /}
function HelloFn(){/ * * * /}
const App = () = >(
<div>
<HelloCls />
<HelloFn />
</div>
);
ReactDOM.render(App, document.getElementById('root'));
Copy the code
Click me to view the source code
Depend on the collection
Both type of component and function component, to get the state object has been converted into a Proxy agent object, collect data dependent on the current rendering, so if there is a conditional state of reading, delay of deconstruction is recommended for the wording, so that the smallest dependence on every rendering lock list, reduce redundant rendering, for better performance.
function HelloFn(){
const { state, setState, syncBool } = useConcent({module:'hello'.state: {show:true}});
const changeGreeting = (e) = > setState({greeting: e.target.value});
// When show is true, the current instance relies on ['greeting'], and any changes to the value elsewhere trigger the current instance to rerender
// When show is false, the current instance has no dependencies, and changes to the new greeting value anywhere else do not affect the current instance rerender
return (
<>
{state.show?<input value={state.greeting} onChange={changeGreeting} />:'no input'}
<button onClick={syncBool('show')} >toggle show</button>
</>
);
}
Copy the code
Consuming module state across multiple modules
When a component needs to consume data from multiple modules, the CONNECT parameter can be used to declare multiple modules to be connected.
Connect multiple modules using the connect parameter
As shown in the following example, connect the bar and baz modules and obtain the target module status via ctx.connectedState:
@register({connect: ['bar'.'baz']})
class extends React.Component{
render(){
const { bar, baz } = this.ctx.connectedState; }}Copy the code
The module state retrieved from connectedState still has dependency collection behavior, so deferred deconstruction is recommended if conditional rendering statements are present
Use setModuleState to change the state
Modify the target module state by calling the instance context apictx.setModuleState
changeName = e= > this.ctx.setModuleState('bar', {name: e.target.value})
Copy the code
conclusion
This article just shows you the basics of the API to get you started on Concent. If you’re an old driver, especially now that Vue3 One Piece has been announced, and you don’t like the way the code is organized, don’t be too quick to dismiss it. Check out the other features on the website. There will be some highlights you’ll like, including the composition API tailored for React, new module-level features like Reducer, computed, Watch, Lifecycle, and more, all of which will be covered in a crash course.
Concent to carry a set of complete solutions, support the development of progressive react components, namely do not interfere with the react and component form itself to the development of philosophy, but also can get huge performance gains, which means that we can to the incremental iteration, the top state of module partition, derived data management, the classification of the event model, Business code space can be gradually in the development process of the outline and spun off, its process is smooth, silky, also allows us to top-down plan as a whole, the development of a start all the domain model and business module abstract clearly, at the same time in the iteration process can also be very fast flexible adjustment and affects the whole architecture of the project.