This lesson explains how you can build larger trees of react component and how they are managed efficiently by MobX. You will learn how to pass observable data structures around in props and how the Devtools can be used to analyze the performance of your UI.
[00:00] Here we have our list of temperatures again. We have initialized this with the three temperatures and we have our app that loops of these temperatures and renders them. Here they are.
[00:14] This view is a bit silly. Let's fix this. What we want to do is when we click this temperature that it increases the temperature. At the convenience you already introduced the increment action which just adds one degree to the temperature. What we can do now is simply add an onclick handler, and we say that it needs to increment the temperature. Now, if you click it, the temperature increases.
[00:43] That works but it isn't very efficient, because as you can see, every time we click one of the temperatures, all of them re-renders. That is because there's only one component which renders all of the temperatures, so it has to react to all of the temperatures. Let's fix that. Let's use a divide and conquer strategy and split up those components.
[01:06] So far we have this status finish components which takes properties and produces their rendering. We simply declare a new class and this time, we use the ES6 class of style to demonstrate how that works. We call this class T-view, which isn't the best name, but the temperature is already in use in this single file. In a real app, you would, of course, split this up into separate files.
[01:33] We move the list elements to the new render function. We grab the temperature from the properties and we invoke this new component from our original app components. We still need to pass in a key for that we'll be able to reconcile these components, but we no longer need the key and the new components. Let's remove that.
[01:58] Then we run this and now click the list items. Nothing happens and that is because our new component isn't reactive. We can simply fix that by adding the observer decorator. Now we render again, and we once again use the desk view to see when the components render, and we see now that they individually re-render when we click them.
[02:25] Also, if we push new temperatures onto the list, you see that MOBEX has now optimized the rendering of our components. The parent component is re-rendered because an item is added and the new child is rendered, but the other childs aren't.
[02:41] When MOBEX starts behind the scenes it's implementing shoot component updates so that parent components can render independently of their childs and childs independently of their parents. If we change another one we see that MOBEX now exactly has determined which components need to be updated for each change.
[02:58] Now we have split up our small components, but this onclick handler here inline is still a bit ugly. Let's refactor that nicely to an action. We now nicely have split off our event handler into a separate action which is invoked from rendering and still works as expected.
[03:21] Now we have two real components. One, status finish component which maps over our temperatures, and we have the temperature view components, which has a simple action and renders independently of its parents.
observer
only observers data that is used in its own render function, but not data that is used in child components. So the first function reacts to any change that happens to the temperature collection because it loops it. Not just addition / removal but also if an element is replaced at a certain index. And the second indeed reacts to changes to the rendered attributes of the temperature object. If both the collection and a temperature are changed by the same action, both components will re-rendered. Other Temperature components with an unchanged temperature object won't re-render though.
Question: seeing this: @observer class TView extends React.Component {...}. Does that means that If I'm using a third party library I'd have to create a wrapping component in order to add the "@observer" keyword?
Feels to me that If write components and prefix them with @observer then I'm going to be tied to MobX. Thoughts? Thank you!
Hi! Just wondering why onTemperatureClick
in the TView
component needs to be decorated with @action
. Removing the decorator seems to (superficially at least) produce the same result.
After the separation - why wasn't the observer on the first function enough to trigger the a view change when a temperature was clicked? Is the first function now observes only added/removed temperatures and the second one observes actual temperature changes? What will happen if a change needs to re-render both a parent component and a child component? Thanks :)
It is because you are using mobX props in the child component. If you use setState and use state props then the component will render itself without adding @objserver.
After the separation - why wasn't the observer on the first function enough to trigger the a view change when a temperature was clicked? Is the first function now observes only added/removed temperatures and the second one observes actual temperature changes? What will happen if a change needs to re-render both a parent component and a child component? Thanks :)