React-router or not? - javascript

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.

Related

About React, Suspense, lazyLoad and preloading/rendering elements

I am studying the <Suspense> and React.lazy() concepts, and I would like to better understand what happens in order to add some logic into an existing app.
Let's start with the definitions:
The React.lazy function lets you render a dynamic import as a regular component.
(render highlighted by me)
and
If the module containing the OtherComponent is not yet loaded by the time MyComponent renders, we must show some fallback content while we’re waiting for it to load[...]
(loaded highlighted by me)
Now, the Suspense definition uses the term load, lazy() uses render.
Let's add some code to the concept.
const ComponentOne = React.lazy(() => import("./ComponentOne"));
const ComponentTwo = React.lazy(() => import("./ComponentTwo"));
function BigBang() {
return (
<Suspense fallback={<SplashScreen/>}>
<section>
<ComponentOne/>
<ComponentTwo/>
</section>
</Suspense>
);
}
Fine. The idea is that we are lazy-loading ComponentOne and ComponentTwo.
While this process is not over, we will display SplashScreen.
THE QUESTION
Now, let's assume that I have some import to some local images into ComponentOne and ComponentTwo (I will add the code only for one, let's assume there is something similar for the other one):
import avatar from "../../img/avatar.svg";
import logo from "../../img/logo.svg";
export default class ComponentOne extends React.Component {
componentDidMount() {
console.log("ComponentOne#componentDidMount");
}
render() {
console.log("ComponentOne#render");
return (
<div style={{display: 'none'}}>
<img src={avatar}/>
<img src={logo}/>
</div>
);
}
}
Now it should be clear what I would like to ask:
Does the SplashScreen disappear when ALL the imports are loaded? In other terms, when the SplashScreen disappear, can I assume that all the images in the ComponentOne and ComponentTwo are already loaded?
This is the main question.
A secondary question (that seems related to me, but if it's not I can open another thread) is: if the answer to the previous question is "NO", what is the best strategy to be sure that the images/fonts/"api response"/"other resources" are loaded before rendering, possibly maintaining the logic because of an already existent flow? Direct fetch() to resources is not supported at the moment.
Suspense waits for the dynamically imported component file (lets say 0.js) to get fetched.
Now as soon as 0.js is loaded and starts parsing, Suspense stops showing SplashScreen and delegates control the your component. Whatever happens next is not lazy loading. It would just be like what would happen if you did a static import.
In your case, the two images would be loaded only after the SplashScreen goes away. Now if you want to preload / lazy load the images there are several ways to go ahead with that.
1) If you are using webpack, you can use url-loader to inline the images as data-uri. But beware, that this might increase your bundle size and also you lose out on browser caching of images which are usually static.
2) For svgs, you can use the inline-react-svg babel plugin which will convert the svg's to react component so that its part of your bundle (0.js). But it also has the same tradeoff mentioned above.
Hence preloading images has its own tradeoffs. There might be better alternatives such as lazy loading which can be done by easily and also React HOC can be got from several third party libaries.

Material UI Icons not rendering correctly

I'm sorry to ask this again but I cannot for the life of me find out what is going on. I am moving my React app inside an angular app and have got everything working except for the material-ui/icons They are there, they just do not look as they should!
I'm using the most current packages I have the link to the styles in my index.html file and I believe I'm using the Icons correctly.
import { Close } from '#material-ui/icons'
<Close />
This is what they look like on my app.
Bad Icons Image
I don't have any console errors pertaining to material-ui or the Icons.
It should be:
import Close from '#material-ui/icons/Close'
Try this too:
import Icon from '#material-ui/core/Icon';
<Icon>close</Icon>
If your environment doesn't support tree-shaking, the recommended way to import the icons is the following:
import Close from '#material-ui/icons/Close';
If your environment support tree-shaking you can also import the icons this way:
import { Close } from '#material-ui/icons';
Importing named exports in this way will result in the code for every icon being included in your project, so is not recommended unless you configure tree-shaking. It may also impact Hot Module Reload performance if you enable it.
To enable tree shaking click me

Move between nested switches in react router v4

My application has nested switches and I am trying to work out how to create a link that will navigate from one to the other. The app is structured like this:
App
Main switch (/)
Assets switch (/assets/)
Table component with Link
Templates switch (/templates/)
Object viewer component to be linked too
The link component looks like this, with id being the templates UUID:
<Link to={`/templates/${id}`} {...itemProps} />
But when you click the link you go to /assets/correct-UUID.
I can't find any information on this so I'm not sure if this is the classic intermediate problem not covered by tutorials, something that isn't possible or I'm just doing something wrong. Does anyone know which one it is?
That defeats the purpose of the Switch and the router at the same time. From the docs:
Renders the first child <Route> or <Redirect> that matches the location.
Switch basically ensures there's only ever one component rendered in the router. For optimal results, keep your routes in one component, as there is rarely any need to nest them like you do. For example:
import { Switch, Route } from 'react-router'
<Switch>
<Route exact path="/" component={Main}/>
<Route path="/assets" component={Assets}/>
<Route path="/templates" component={Templates}/>
</Switch>
So you define your routes in your app entry point let's say App.js. And that's it, if you want more routes, add them there. If you want nested routes, you nest by literally nesting it: <Route path="/assets/:id/update" component={AssetUpdate} />. That's all there is to it.

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.

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.

Categories

Resources