preface

After graduation, the author worked in a pig factory and got to know redux through the products of NetEase. From the perspective of front-end development, NetEase Meow, as a tool-based Web product, is a product full of challenges and fun in development.

Before this, the author had accumulated little blog, determined to change, and was interested in redux application, so the idea of writing a series of Redux application blog came into my mind.

This series of articles will be in my story two years some summary and result of application development, its purpose has two, one is the hope I am writing this blog series self reflection, self summary, another purpose is to hope for the same application in love story of inspiration, and then you can exchange opinions with each other.

This series does not cover the basics of Redux, but if you have never used Redux before, you can familiarize yourself with the basic concepts on the Redux website.

Complex single module

The front end of the get into the business, we often claim to have is a complex web applications, so that, not because there are a large number of pages, there or have a lot of business logic, but because of who I am several core logic is concentrated in a single module, you can see the following figure interface, edit page in this page is for report. There are also several core product pages.

In this editing page, there are PPT-like interaction modes, including chart dragging, resize, canvas zooming, copy and paste, style setting, etc. The flexibility and complexity of the interaction mode is the most complex I have encountered so far. You can visit the trial version of this product to have a taste of it. www.youdata.163.com

How does the application manage state without introducing Redux?

Yes, as the title suggests, Redux is for application state management. Since today’s topic is Redux, we must take a look at how our application managed state before redux was introduced.

The simple answer is that our application’s state management relies heavily on state transfer between parent and child components.

So let’s take one-way data flow as an example to talk about how state management works and the limitations of state management. (Bidirectional binding is similar, you can think about it yourself)

Note: the following picture was found in a blog on the Internet, forgot the address, here did not post source sorry.

Simple scenario: parent-child component tree

State is passed from parent to child components as properties.

This is the simplest case. In the code below, the ParentComponent ParentComponent passes the loading state as an attribute to the ChildComponent ChildComponent.

ParentComponent. Js:

render() {
    const { loading } = this.state;
    return (
        <ChildComponent loading={loading}>
            This is content
        </ChildComponent>)}Copy the code

A slightly more complex scenario: two sibling components share state and change that state in one of them.

  1. Promote this state and the functions that modify it to the common ancestor of both components;
  2. Modify this state by calling a function passed down from a child component;
  3. This state is modified in the parent component;
  4. The parent component itself triggers a re-update;
  5. The child of this parent triggers an UPDATE;
  6. The state of the child component is updated;

The above steps are the basic steps to address the state management of this scenario, which is simply state ascending and then passing down. Does it feel like a little bit of trouble? If you find the above language difficult to understand, take a look at the following code, which should be easy to understand if you’ve written React before.

Parent.js

changeLoading(loading) {
    this.setState({ loading });
}

render() {
    const { loading } = this.state;
    return (
        <div className="m-parent">
            <ChildComponentA 
                loading={loading} 
                onChange={value => this.changeLoading(value)}
            />
            <ChildComponentB loading={loading} />
        </div>
    );
}
Copy the code

ChildComponentA.js

render() {
    const { loading, onChange } = this.props;
    return <div onClick={()= >onChange(! loading)}>a loading: {loading}</div>;
}
Copy the code

ChildComponentB.js

render() {
    const { loading } = this.props;
    return <div>b loading: {loading}</div>;
}
Copy the code

More complex scenarios: Component tree hierarchy deepens

This component tree is not only deeper and has more branches than the above scenario, but from the perspective of application state, the core steps are still the idea of the above scenario: states (functions) are promoted and properties are passed down, and multiple states are nothing more than repeated multiple times.

What are the downsides of this?

  • ** causes a lot of unnecessary attribute passing. ** In the process of state transfer, there is unnecessary waste because we need to promote the state to the common ancestor component and then layer by layer to the target component, passing through unrelated components that don’t actually need the state.

  • ** Maintenance becomes difficult. ** If you add state, or if the component that shares state changes (which is common in business scenarios), then you have to change not only the component that uses the state, but also the component that passes through the property. Maybe you just need to change the name of a variable. So this kind of state management can be quite cumbersome to maintain.

The component tree structure is inconsistent with the data flow relationship

Above, we introduced a state management approach that relies on a tree of components to transfer state. We also saw that such an approach is inconvenient and difficult to maintain once the business is complex.

As the saying goes, you can fight a hundred battles without danger of defeat.

Before we discuss how to solve this problem, let’s take a closer look at why such state management is full of limitations. The root causes are:

The component tree structure is inconsistent with the data flow relationship

What does that mean?

For example, we have a component tree:

In this component tree, both B and E use state_A, so state_A must be promoted to component A for management. From the perspective of data flow, B and E should be peer nodes relative to A, and their data tree structure should be as follows:

As the picture shows, it is clear that the component tree structure is inconsistent with the data tree structure, which is the problem.

Introduce Redux intermediaries

Knowing that the root cause of the above state management mess is the inconsistency between the structure of the component tree and the structure of the data tree, we can address the problem. Since you want to get rid of the component tree structure, you should decouple the state entirely.

This is where a third party needs to step in and take the state out of the component tree and hand it over, which is known as the mediator pattern.

Redux is such a mediator, and when we introduce Redux, our application’s state management becomes:

  • All states (modification functions) are managed by Redux, corresponding concepts of Redux are state and Reducer.
  • When a component wants to change its state, it simply notifies Redux to do so, which is the Dispatch process.
  • When redux receives the action, it changes the state and then throws the state to the component that wants it. This process is known as connect and mapStateToProps in React-Redux.

So let’s see if WE’ve solved our state management problem,

conclusion

The topic of redux state management is over here, and there will be a series of updates on redux related practices and understandings. There are a lot of content to write, such as: Undo redo implementation, multi-person collaboration implementation, high reducer application, immutable data introduction and use, container components and display components introduction and use, asynchronous scheme selection and so on, so this series can be written for a long time, if you have more interested points, you can leave a message in the comment section, I will consider writing first.