Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Sometimes Vueâs reactivity system isnât enough, and you just need to re-render a component.
Or maybe you just want to blow away the current DOM and start over.
So how do you get Vue to re-render a component the right way?
The best way to force Vue to re-render a component is to set a :key on the component. When you need the component to be re-rendered, you just change the value of the key and Vue will re-render the component.
Itâs a pretty simple solution, right?
Youâll be happy to know that there are lots of others ways to do it:
- The horrible way: reloading the entire page
- The terrible way: using the v-if hack
- The better way: using Vueâs built-in forceUpdate method
- The best way: key-changing on your component
Except here is where Iâm going to ruin it for you.
If you need to force a reload or force an update, thereâs probably a better way.
Itâs likely that youâre misunderstanding one of the following tricky things:
- Vueâs reactivity
- Computed props
- Watched props (sometimes)
- Not using a :key attribute with v-for
Now, there are valid use cases for forcing an update. Most of these will be solved using the key-changing technique thatâs at the bottom of this article.
Horrible way: reload the entire page
This is one is equivalent to restarting your computer every time you want to close an app.
I guess it would work some of the time, but itâs a pretty bad solution.
There isnât really much more to say about this. Donât do it.
Letâs look for a better way.
Terrible way: the v-if hack
Vue comes with the v-if directive that will only render the component when itâs true. If itâs false, the component will not exist at all in the DOM.
Hereâs how we set it up for the v-if hack to work.
In your template youâll add the v-if directive:
In your script youâll add in this method that uses nextTick:
This is whatâs going on here:
- Initially renderComponent is set to true, so my-component is rendered
- When we call forceRerender we immediately set renderComponent to false
- We stop rendering my-component because the v-if directive now evaluates to false
- On the next tick renderComponent is set back to true
- Now the v-if directive evaluates to true, so we start rendering my-component again
There are two pieces that are important in understanding how this works.
First, we have to wait until the next tick or we wonât see any changes.
In Vue, a tick is a single DOM update cycle. Vue will collect all updates made in the same tick, and at the end of a tick it will update what is rendered into the DOM based on these updates. If we donât wait until the next tick, our updates to renderComponent will just cancel themselves out, and nothing will change.
Second, Vue will create an entirely new component when we render the second time. Vue will destroy the first one and create a new one. This means that our new my-component will go through all of its lifecycles as normalâââcreated, mounted, and so on.
On a side note, you can use nextTick with promises if you prefer that:
Still, this isnât a great solution. I call it a hack because weâre hacking around what Vue wants us to do.
So instead, letâs do what Vue wants us to do!
Better way: You can use forceUpdate
This is one of the two best ways to solve this problem, both of which are officially supported by Vue.
Normally, Vue will react to changes in dependencies by updating the view. However, when you call forceUpdate, you can force that update to occur, even if none of the dependencies has actually changed.
Here is where most people make the biggest mistakes with this method.
If Vue automatically updates when things change, why should we need to force an update?
The reason is that sometimes Vueâs reactivity system can be confusing, and we think that Vue will react to changes to a certain property or variable, but it doesnât actually. There are also certain cases where Vueâs reactivity system wonât detect any changes at all.
So just like the last methods, if you need this to re-render your component, thereâs probably a better way.
There are two different ways that you can call forceUpdate, on the component instance itself as well as globally:
Important: This will not update any computed properties you have. Calling forceUpdate will only force the view to re-render.
The best way: key-changing
There are many cases where you will have a legitimate need to re-render a component.
To do this the proper way, we will supply a key attribute so Vue knows that a specific component is tied to a specific piece of data. If the key stays the same, it wonât change the component, but if the key changes, Vue knows that it should get rid of the old component and create a new one.
Exactly what we need!
But first weâll need to take a very short detour to understand why we use key in Vue.
Why do we need to use key in Vue?
Once you understand this, itâs a pretty small step to understanding how to force re-renders the proper way.
Letâs say youâre rendering a list of components that has one or more of the following:
- Itâs own local state
- Some sort of initialization process, typically in created or mounted hooks
- Non-reactive DOM manipulation, through jQuery or vanilla APIs
If you sort that list, or update it in any other way, youâll need to re-render parts of the list. But you wonât want to re-render everything in the list, just the things that have changed.
To help Vue keep track of what has changed and what hasnât, we supply a key attribute. Using the index of an array is not helpful here, since the index is not tied to specific objects in our list.
Here is an example list that we have:
If we render it out using indexes we will get this:
Which displays:
Evan - 0Sarah - 1James - 2
If we remove Sarah, we will get:
Evan - 0James - 1
The index associated with James is changed, even though James is still James. James will be re-rendered, even if we donât want him to be.
So here we want to use some sort of unique id, however we end up generating it.
Before when we removed Sarah from our list, Vue deleted the components for Sarah and James, and then created a new component for James. Now, Vue knows that it can keep the two components for Evan and James, and all it has to do is delete Sarahâs.
If we add a person to the list, it also knows that it can keep all of the existing components, and it only has to create a single new component and insert it into the correct place. This is really useful, and helps us a lot when we have more complex components that have their own state, have initialization logic, or do any sort of DOM manipulation.
Maybe that detour wasnât so short. But it was necessary to explain how keys in Vue work.
Anyways, letâs get on with the best method of forcing re-renders!
Key-changing to force re-renders of a component
Finally, here is the very best way (in my opinion) to force Vue to re-render a component.
You take this strategy of assigning keys to children, but whenever you want to re-render a component, you just update the key.
Here is a very basic way of doing it:
Every time that forceRerender is called, our prop componentKey will change. When this happens, Vue will know that it has to destroy the component and create a new one.
What you get is a child component that will re-initialize itself and âresetâ itâs state.
A simple and elegant way to solve our problem!
Just remember, if you find yourself needing to force Vue to re-render a component, maybe you arenât doing something the best way.
If, however, you do need to re-render something, choose the key-changing method over anything else.
Check out my articles as soon as they come out at michaelnthiessen.com! I re-post them here a few weeks later.
Originally published at michaelnthiessen.com.
The correct way to force Vue to re-render a component was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.