And an effect just describes how an operation interacts with the data, whether it reads it, changes it, modifies it, and so on. And this is really important later on for memorization, because a compiler needs to know which operations are safe to cache, and which could break if they were cached incorrectly. So there are six types of effects. So in our case, we first have some read effects, like accessing a method like filter or length. So a read effect doesn't change anything about the code. So any read effect is perfectly safe for caching. We also have some store effects, and these are store effects where we assign new values. So these are safe to cache, as long as the value that's being stored does not depend on any mutable data. Now we also have capture events, and these are events for loading values from outer scope. So function parameters or previously stored variables. And these create dependencies that the compiler needs to track to have the correct memorization. We also have mutate effects. These are operations that might modify depending on what happens at run time, and that's the majority of it. Lastly, we also have freeze effects, and these make values immutable so they guarantee that they cannot be modified later. And the compiler just adds these to make sure that the data won't change, making them safe to cache.
Okay. So finally at this point, the compiler now understands what each operation does and how it affects the data. But it still doesn't know which values change between renders. So for example, we know that instruction three has a read effect when accessing filter, but that doesn't tell us if the user's array can change between renders. Maybe it's always the same static array, maybe it comes from props or state and so on. So the effect analysis tells us the potential for change, but it doesn't tell us whether it will actually change or the change that actually matters in React, if it can change between re-renders. So now it's time for the next phase, reactive analysis. So during this phase, the compiler has to figure out which specific values in this component are reactive, meaning that they can change between renders. Just to make the code a bit more readable, I'll just remove the types, because otherwise I have to make the font really small, but they're still there. So the compiler first starts by looking at the source of each value, and to check whether it's reactive, it begins with the values that are definitely reactive, which are the function parameters are always reactive, because they come from props, they can always change between renders, and also hook calls produce reactive values, like use state, use context, but in this case we only have function parameters. So now the function parameter is marked as reactive, but it then traces forward through the data flow with a simple rule. If a reactive value flows into an operation, this output becomes reactive too. And what this means is, looking at our example, the user's parameter starts as reactive, because it's a function parameter, but we now have a reactive value, 23 becomes reactive as well, and then we load users on line two, so 24 becomes reactive as well. Then we access the filter property on 24, so this also gets reactive, because we loaded the reactive user prop, so 25 also becomes reactive, and so on. So anytime there's any reactive input, the output becomes reactive as well.
Comments