Former article juejin. Cn/post / 694197… Subsequent juejin. Cn/post / 694276…

For now, we need to clean up our code and integrate appContext.js, connect.js and createnewstate. js into redux.js:

As a result, app.js uses only two apis:

import { appContext, connect } from "./redux";
Copy the code

Student: What do you do next?

Optimize the appContext to see how it is used:

As you can see, appContext is primarily used to initialize appState and setAppState. Currently, we use App state as global state, which is actually a big performance problem

Student: What is it?

Fang: Let me show you this bug. First, I add a log to the first line of each of the three sons

Then, look at the log in the console:

Do you see any problems?

Student: Is there a problem?

Fang: Haven’t you noticed the extra render? I called Dispatch from the UserModifier in the second son. In theory, I only need to execute the eldest and the second son functions (because the children of both components read user). Why execute the youngest son function? This is redundant render, right?

Student: Oh, right…

Fang: Do you know what this means? This means that every time we make a tiny change to state, we’re rendering the App

Student: Because you called the setAppState function of the App, right?

Yes, as soon as this function is called (and a new appState is passed to it), the App must be reexecuted, which must cause all the child components of the App to be reexecuted, unless the child components are cached:

Obviously, most people don’t cache every descendant component.

Student: What about that?

Fang: The problem is that we “use App state as global state”, we can consider to separate the appState, so I declared a store in redux.js and exported it:

Then pass the store to the value of the context:

This eliminates the dependency on App state.

Student: So everything that uses appState has to be store.state

Fang: That’s right, since we made the User modifier and UserModifier get state and Dispatch from Connect last class, we just need to modify Connect:

Student: Is that all?

Fang: Not at all. Run the page and you will find “user.name cannot be modified”. Because store. State changes don’t trigger any component updates, React usually calls setState to trigger component updates.

Student: Isn’t it back to square one? We started with setState

We started with App setState. This time we can use Wrapper setState

Student: But how does the Wrapper know that store.state has changed?

The Wrapper can subscribe to changes in store.state, just add a subscribe interface to the store:

Then, after setState is run, iterate over all fn calls:

Student: You implemented a publish subscription with just a few lines of code?

Fang: Yes, but the implementation is rather crude. Next we need to listen for store.state changes inside the Wrapper:

Student: Re-render the Wrapper if state changes?

Fang: Yes, but the question is how to re-render the Wrapper? Function components do not provide a forceUpdate interface. Here’s a trick we’re going to use:

Update({}) on line 26 equals forceUpdate()

Student: You took advantage of {}! == {} this feature!

F: Clever, use Symbol() can also achieve the same effect. Let’s take a look at our optimization results:

See, when changing user.name, none of the three child components are re-executed, only the User modifier and UserModifier are re-executed.

Student: So every time you change state, only the connected components are rerendered?

Fang: that’s right.

Student: Eh? Then I have a question, if a component is connected, but it is not user.name will be re-rendered when user.name is updated?

Fang: At the moment

Student: Can it be optimized?

Fang: Isn’t that easy? Each Wrapper compares its dependency values to see if they have changed (use ref to store the last value) and does not update({}) if they have not changed…

Student: So how does each Wrapper know whether it depends on state.user or state.group?

State => ({user: state.user}); State => ({group: state.group})

Student: That’s what the first parameter of Redux’s connect, mapStateToProps, is for

Professor: Well, the current code for damp-wave-1uFWd-codesandbox will be explained in the next video

Student: Ok!

To be continued…