effect
The effect method is the core of the reactive, called the side effect function. The initial value operation will be performed by default. As long as the value is selected, the GET method will be called, and we can store the corresponding Effect function. Later, when we update the state data that the effect function relies on inside, we will call the corresponding effect function at the beginning and the view will be updated
Ex. :
Note: State is associated with effect. Only when the corresponding data is changed, the corresponding effect will be executed
Core principles
The first step
Create effect. Ts file, export effect method, internal rely on a method to create a reactive createReactiveEffect, outer layer do formatting, inner layer do reactive.
Note: Effect returned internally is a function
Based on the lazy attribute in the second parameter option, if it is not a trueeffect, it is executed once by default
The second step
Start writing the logic for Create Active Effect
- We need to give effect a unique identifier so that we can track where and to whom it belongs
- Create an external serial number uid. Each time createReactiveEffect is called, add an id to the created effect with a value of UI ++
- We need to add an _isEffect flag to effect to indicate that this is a reactive effect with a value of true and an underscore field to indicate that this is private
- We also need to record the original function for effect, raw = fn
- Let’s save the choices as well
The third step
We said that effect will be executed once by default, so let’s make fn run once in the reactiveEffect function, which is the function passed in by the user
When the user calls effect, it will take a value, and that value will trigger the property’s get method and go to the corresponding Hanlders. Earlier we said that vuE3’s proxy mode is lazy. So we do dependency collection at this point, collecting effects
The third step
Dependency collection in Reactive, which is where we left off at the end of the previous article.
First of all, we write a track method in createrGetter for dependency collection, and this track method is written in the effect file. We export the method and introduce it in the Reactive file
- Which object and operation do we need to tell tract? Which property
- Create a new file, operators.ts, just for the operators
Now let’s go and write track
Question: How do we get the corresponding effect in track?
The answer is global variables, and you can use global variables to correlate
Problem one: We might write code like this
It’s going to take the last one, it’s going to mess up, address effect should still be effect1\
So we can stack it to ensure that the effect of each property collection is correct
Effect is pushed onto the stack each time it is executed, and then the current effect is saved to the global variable, and then the function passed by the user is called. At the end of execution, effect is pushed off the stack, and then the last one in the current stack is assigned to the global variable.
In this way, the order of effect is guaranteed, and the effect obtained in track is correct
Problem two: We might write code like this
Will be dead loop, will keep refreshing \
So let’s see if this effect is already on the stack before we add it to the stack
To sum up: we have implemented the effect function to collect the current corresponding properties of an object
The fourth step
It is possible for a property of an object to correspond to multiple effects, so we will now use a data structure to associate them
We can use weakMap for correlation
New a WeakMap outside
If activeEffect equals undefined, it is not used in effect
And then we can correlate
Resolution:
- I pay first in Target, and the first time I take the value I am
- If I don’t get it, then I put it in here, key is the target, and the second argument is a map, and this new map is also assigned to the current depsMap
- Then evaluate from targetMap to see that there is no dependency collection
- If not, set the dependency collection to a set in the current map
- If there is no activeEffect in the current set, add the dependency to the current set, so that the dependency is collected in the last set data structure
- It’s a little bit convoluted, but the structure that I end up mapping is something likeLike this
There may be some people who have no doubt about using weakMap and Map, but have doubt about the last set data to store effect, why do they use set to store effect in the end?
- If you apply an effect to an object more than once, then if you do not use the set property, you save the same effect
If you feel that you have gained something, please use your little hands to save, thank you! How to predict the future, and listen to the next time to break down ~