Vue Keep-Alive - Component won't stay alive during route changes - javascript

I defined the main page of my vue app to look like this:
<div class="wrapper">
<keep-alive>
<app-header></app-header>
</keep-alive>
<router-view></router-view>
</div>
<script>
import appHeader from '../components/Header';
export default {
components: {
appHeader
}
/* etc... */
}
My app UI is basically this Dashboard, with many different routes and sub-routes paths to show many pages, but in all pages (components) I want to show the app-header at the top of the page.
The problem is that I noticed recently, with every button clicked (that changes vue-router's route to another page), the app-header gets recreated (the created() lifecycle hook function is called)
I really don't understand why, since I added keep-alive, shouldn't it be rendered once?
Please help me figure this out, I am stuck, I literally researched the entire internet about it.
Thanks in advance

The keep-alive will work only in the section which is wrapped by the <keep-alive> tag. Here, only the app-header component will keep alive. If you need to apply this to all the components within the routes, you have to put the <router-view> inside <keep-alive>.
Eg:
<keep-alive>
<router-view></router-view>
</keep-alive>
Now the keep-alive will work for all the routes.

Answer from Rijosh is applicable only for Vue 2 and its router (Router v3.x). If someone uses Vue 3 (and Router v4.x), then code for <keep-alive> and <router-view> looks like this:
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
More can be found in documentation here.

Related

React-router or not?

I'm currently making a react application with create-react-app
It's a single page with several sections (Home / About / Contact ...)
Each section is a component that I export, of course.
Currently my App.js is like this :
App.jsx
import Menu from './components/menu/Menu';
import Header from './components/header/Header';
import Home from './components/sections/00_home/Home';
import About from './components/sections/01_about/About';
import Works from './components/sections/02_works/Works';
import Contact from './components/sections/03_contact/Contact';
const App = () => {
return (
<div className={styles.Container}>
<Menu />
<Header />
<Home />
<About />
<Works />
<Contact />
</div>
);
};
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
/* CSS */
import './index.css';
/* JSX */
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
To go from one section to another I use the anchor tag href's
For example in the home section, I have links to the other sections, same for the menu.
So far so good for me, but I'm wondering a question.
Should I use react-router? If so, why?
In which situation should I use it ?
If someone could enlighten me on that, that'd be great.
Is the way I currently code unconventional?
Ced.
From your question, perhaps you misunderstood the single-page application (SPA) theory which is the main reason for why we have to adopt React Router instead of html hrefs. A brief clear overview from quick gg is that "React Router, a dynamic, client-side routing, allows us to build a single-page web application with navigation without the page refreshing as the user navigates. React Router uses component structure to call components, which display the appropriate information."
So when you are having some shared components and you want to write less code and avoid reloads whenever user navigate around which is quite annoying then React router is a solution you need.
There are few differences in both which are quite important:
React-router: You can define the links you wanna go to and with the help of Link tag you define the URL in other components. In this situation, the Link tag will not refresh the page but instead would go onto the corresponding page but a href will refresh the page.
It might be difficult for you to pass information between components, as it is an important concept behind react.
Another would be an example, like if you are on /classes link and you go for a href tag, then it that case it will redirect you (i.e., you are using a relative path) to the /classes/teachers page, but you might want to go to /teachers URL. With the lp of Link and router, when you provide /teachers, it will redirect you to this URL
I have also started working on react and these are the points I came through.

Structure: Where put navigation bar component (Vue/ React)

I have a quick question regarding components in frameworks like Vue or React (I'm using Vue):
I am building a relatively simple web app with a navigation bar which is visible on all pages.
Where would you put the navigation bar component? On every single page? Or only once on the main parent page where all the child components get loaded?
Hello you can call components from anywhere, you just need to create the component in a separate file in your components folder. (mycomponent.vue)
<template>
<h1>I am a component</h1>
</template>
and then in your view you need to import that component with:
import mycomponent from './mycomponent.vue'
and finally you just need to declare it inside your instance like this.
export default {
components: {
mycomponent
},
// ...
}
if you do this you are going to be able to print that h1 using in your view this tag.
<mycomponent></mycomponent>
it's like if you create your own html tag.
it's very simple, greetings, hope it helps just do it with your nav bar no with an h1.

ReactRouter route render component to container element

My issue here is that I need to render separate route components to elements created by the backend. It's irregular I'm sure. Essentially I'm starting with an html document and need to render route components to particular elements in the dom.
Example:
If I have four components that each need to be rendered to a pre-generated element.
<body>
<div id="elone" />
<div id="eltwo" />
<div id="elthree" />
<div id="elfour" />
</body>
Now I need to render my respective components to each of those elements. The issue is that if I call ReactDOM.render within the component it doesn't recognize the router, and it doesn't appear that route has anyway to render to a particular element.
Note: I cannot unfortunately write the document within the JS, it has to be pre-generated. I don't need this to be done through react router if there are other solutions, but the components must recognize the router.
I hate answering my own questions, it makes it seem like no one is really answering questions here.
Anyhow the solution is to use ReactDOM.createPortal instead of ReactDOM.render within the components. Make sure to render the component with the router to an element outside of the container that you want to portal your subcomponents to otherwise you'll obviously clobber the elements that your portals are pointing to.

Mount Multiple ReactJS Components into a single web page

I have multiple, reusable components on a single web page. For example, a popup, sidebar newsletter signup and a simple carousel below the content.
I'm getting the following error
'__reactInternalInstance$lvoo7hroqz' of null
After some research I believe this is down to having multiple calls to react, which makes sense. Every component imports React I believe this is due to the fact react adds id's to each node and it conflicts on each instance that's called.
My question is how would I render multiple components on a single web page? when there's no parent node/container and these elements are called individually throughout the site.
Thanks
EDIT
I have three components that look similar to below.
import React, { Component } from 'react'
export default class test extends Component {
render(){
return (<h1>test one</h1>)
}
These three individual components appear randomly around my page.
<div>
<header>
Some HTML/PHP here
<ReactTestComponent />
</header>
<div>
content here
<AnotherComponent />
</div>
<FinalComponent/>
</div>
These three components do not always appear on the same page, for instance "FinalComponent" may be missing from the next page (depending if you're on a archive page etc) so all my components need "import React from 'react'" at the top of each file.
When I render multiple components on a single page. I get the following errors. (Based on the amount of components rendered, if I render two components I get two of the same error)
Uncaught TypeError: Cannot read property '__reactInternalInstance$lvoo7hroqz' of null
at Object.getClosestInstanceFromNode (react.min.js:504)
at findParent (react.min.js:36970)
at handleTopLevelImpl (react.min.js:36999)
at ReactDefaultBatchingStrategyTransaction.perform (react.min.js:6065)
at Object.batchedUpdates (react.min.js:36768)
at Object.batchedUpdates (react.min.js:1779)
at dispatchEvent (react.min.js:37079)
OK, looking into this a little further I noticed it was a error on my part.
One of the includes was calling the same react file in addition to the footer, so I had two referenced to react.min.js causing the conflict.
Hope this helps someone.

React - remounting components on url change

So I am working on React/redux app with react-router v4.
Page structure is more or less this:
<html>
<head>...</head>
<body>
<aside>
<NavigationComponent />
</aside>
<main>
<ItemComponent />
</main>
</body>
</html>
So I pretty much render an <ItemComponent /> within main depending on the url the user is on, say either /11 or /231. The way I do this currently is use redux's mapStateToProps to retrieve item out of items by id, using react-router injected props, namely params. Then item is passed to as a prop and so the contents get rendered. However, prop changes, namely item changes, only trigger difference rerenders.
How would I accomplish unmounting current <ItemComponent /> and mounting a new one? Or better yet, what's the best way to animate this component, say when entering and leaving (triggered by url change)?
I managed to hack something around using ReactTransitionGroup addon, however I am interested in the cleanest way to accomplish this.
Thanks a lot!

Categories

Resources