react router only update url - react-router

When I click the profile navigator the url change but the page doesn't. I try to move the router tag into index.js, using withRouter in my App.js and Profile.js but it's not work. I already use exact inside my url for homepage. This the code App.js
function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/profile" component={withRouter(ProfilePage)} />
</Switch>
</Router>
);
}
And this is Home.js
const home = () => {
return(
<Router>
<div className="container">
<img src={environment} alt="environment" className="environment"/>
<Link to="/email"><img src={pos} alt="pos" className="pos"/></Link>
<Link to="/profile" className="profile"><img src={profile} alt="profil"/></Link>
<Link to="/experiences"><img src={experience} alt="experience" className="experience"/></Link>
<Link to="/projects"><img src={project} alt="project" className="project"/></Link>
</div>
</Router>
);
}
Profile.js
const Profile = () => {
return(
<div className="profile-container">
<h2>Profile</h2>
<span className="line"></span>
<img src={photo} alt="photo-profile" className="photo-profile"/>
</div>
</div>
);
}

You should Update Home page and remove Router page:
const home = () => {
return(
<div className="container">
<img src={environment} alt="environment" className="environment"/>
<Link to="/email"><img src={pos} alt="pos" className="pos"/></Link>
<Link to="/profile" className="profile"><img src={profile} alt="profil"/></Link>
<Link to="/experiences"><img src={experience} alt="experience" className="experience"/></Link>
<Link to="/projects"><img src={project} alt="project" className="project"/></Link>
</div>
);
}
I think this the problem you try to call Router twice.

Related

How to render embedded html with multiple tags in react

I'm embedding a request form. I want to click a button in react to open the form, then add a button to go back/exit. Ive added the HTML tags into index.html but I'm having a hard time with control. I toggle the display: none/block to get it to appear/ disappear which works fine (also have to toggle display for all of the react app so only the form is shown.).
The Html I'm trying to embed has 3 tags. I'm not able to find an answer of how to use dangerouslySetInnerHTML with multiple tags.
I've also just tried to use dangerouslySetInnerHTML twice and just gave the react div the needed reference id. No luck, just a blank white page.
<div id="f6f2802e-49e8-477b-b405-8b2b18dded97"></div>
<link rel="stylesheet" media="screen" href="https://d3ey4dbjkt2f6s.cloudfront.net/assets/external/work_request_embed.css" />
<script src="https://d3ey4dbjkt2f6s.cloudfront.net/assets/static_link/work_request_embed_snippet.js" clienthub_id="f6f2802e-49e8-477b-b405-8b2b18dded97" form_url="https://clienthub.getjobber.com/client_hubs/f6f2802e-49e8-477b-b405-8b2b18dded97/public/work_request/embedded_work_request_form"></script>
12 hours of trying.
(https://codesandbox.io/s/l9qmrwxqzq)
This worked pretty much immediately. Once I found it.
'''
import React from "react";
import ReactDOM from "react-dom";
import { Helmet } from "react-helmet";
import "./styles.css";
function App() {
return (
<div className="App">
<h1>Check if Helmet works as expected with script tags</h1>
<p>Check console output - you will see $ is undefined</p>
<Helmet>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"
/>
<script>
{`
console.log('Test', typeof $);
`}
</script>
</Helmet>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
'''
My final product
'''
import React from "react";
import { Helmet } from "react-helmet";
export default class Jobber extends React.Component {
render() {
return (
<div className="Application" id="f6f2802e-49e8-477b-b405-8b2b18dded97">
<Helmet>
<div id="f6f2802e-49e8-477b-b405-8b2b18dded97"></div>
<link
rel="stylesheet"
media="screen"
href="https://d3ey4dbjkt2f6s.cloudfront.net/assets/external/work_request_embed.css"
/>
<script
src="https://d3ey4dbjkt2f6s.cloudfront.net/assets/static_link/work_request_embed_snippet.js" clienthub_id="f6f2802e-49e8-477b-b405-8b2b18dded97" form_url="https://clienthub.getjobber.com/client_hubs/f6f2802e-49e8-477b-b405-8b2b18dded97/public/work_request/embedded_work_request_form"
/>
</Helmet>
</div>
);
}
}
'''

How to fetch multiple google fonts

I'm working on a personal project in NextJS which uses around 5 Google fonts.
The fonts are being fetched only if the page New is reloaded or if I navigate to the page using <a></a> tag instead of <Link></Link>.
This is my current code for the page that requires the fonts,
export async function getStaticProps() {
const fonts = getFontNames(); // returns a static list of strings like ['Monserrat', 'Product Sans', ...].
const fontsLink = "https://fonts.googleapis.com/css2?family=" + fonts.map(cV => cV.replace(/ /g, '+')).join('&family=') + "&display=swap"
return {
props: {
fonts,
fontsLink
}
}
}
export default function New({ fonts, fontsLink }) {
return (
<div className={styles.container}>
<Head>
<title>New</title>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href={fontsLink} rel="stylesheet" />
</Head>
...
</div>
}
This is how I navigate to the page New ,
<Link href="/new">
<a className={styles.card}>
<h2>New →</h2>
</a>
</Link>
Make sure you've disabled browser cache in the network tab before testing fonts.
import PageLayout from "../components/Page/PageLayout"
import Head from "next/head"
export default function About({ fonts, fontsLink }) {
return (
<Head>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href={fontsLink} rel="stylesheet" />
</Head>
)
}
export async function getStaticProps() {
const fonts = ["Monserrat", "Product Sans", "Girassol"]
const fontsLink =
"https://fonts.googleapis.com/css2?family=" +
fonts.map((cV) => cV.replace(/ /g, "+")).join("&family=") +
"&display=swap"
return {
props: {
fonts,
fontsLink,
},
}
}
Using either means of navigation loads the fonts for me.
<Link href="/About">About</Link>
<Link href="/About">
<a>
<h2>About page using Link</h2>
</a>
</Link>

CSS loads after HTML using React and SemanticUI

I have a create-react-app project that uses SemanticUI for styling. My App component is the following:
import React from 'react';
import './App.css'
import { LandingComponent } from '../components/landing/LandingComponent/index'
import { LoginComponent } from '../components/login/LoginComponent/index'
import { DashboardComponent } from '../components/dashboard/DashboardComponent/index'
import { MenuComponent } from '../components/menubar/MenuComponent/index'
import { BrowserRouter as Router, Route, Link } from "react-router-dom"
const App: React.FC = () => {
return (
<>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui#2.4.2/dist/semantic.min.css" />
<MenuComponent />
<Router>
<Route exact path="/" component={() => <LandingComponent />} />
<Route exact path="/login" component={() => <LoginComponent />} />
<Route exact path="/dashboard" component={() => <DashboardComponent />} />
</Router>
</>
);
}
export default App;
Whenever I am working in development mode, I will be able to see the raw HTML for a few milliseconds before the styling kicks in. I figured this would be solved after I build an optimized build using npm run build
However, in a production build, I am having the same issue. I was reading other accounts of people with the same issue, and some recommended using mini-css-extract-plugin. However, I wanted to know if there was a solution to this without adding any additional plugins to my project?
Yes, what you want to achieve is to load the CSS resource as a render blocking resource, which means the browser will load the resource first before rendering the content.
This has nothing to do with React or your build tooling, but rather how web pages work.
This can be achieved by moving the element from your App component to your document . So, move your line to the index.html file that is in the public folder.
Your index.html will then look something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
...
<title>React App</title>
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/semantic-ui#2.4.2/dist/semantic.min.css" />
</head>
<body>
...
Please note, that from web performance point-of-view it is recommended to add the CSS resource only after your title attribute, so that the title gets "rendered" before the browser starts fetching the CSS resource.

React - Sticky Footer issue: Footer at bottom of App component; App component not at bottom of Body

I'm having some trouble with a sticky footer in react. I implemented the flexbox solution I saw on CSS Tricks, but the problem is The footer is at the bottom of the main App component, but the App component is not at the bottom of the body. Here's a picture that illustrates this problem:
Some code:
In the render function of my App component I'm returning this:
render() {
return (
<div className="App">
<div className="all-but-footer">
<Header />
<main className="content">
<Switch>
<Redirect from="/" to="/bio" exact />
<Route path="/bio" exact component={Bio} />
</Switch>
<Route path="/videos" exact component={Videos} />
<Route path="/gallery" exact component={Gallery} />
<Route path="/magnet-podcast" exact component={MagnetPodcast} />
<Route path="/contact" exact component={Contact} />
</main>
</div>
<Footer />
</div>
And of course I'm hooking into the root div with:
document.addEventListener('DOMContentLoaded', () => {
const root = document.getElementById('root');
ReactDOM.render(
<Root />, root);
registerServiceWorker();
});
With the root div in my index.html like so:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>Louis Kornfeld</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
In my CSS I tried giving the App a height of 100% and even tried giving the root div in the index.html a height of 100%. The body's only child is the root div, and the root div's child is App, so I figured giving these all height of 100% would stretch the components but nothing has worked.
Any ideas with how I can resolve this problem?
Normally, when you return an element from a component’s render method, it’s mounted into the DOM as a child of the nearest parent node
If you want to to insert a child into a different location in the DOM , You can make use React Portals
The one which worked for me is react-portal you can install it as a project dependency npm install --save react-portal
And inside your component you can :
import { Portal } from 'react-portal';
<Portal>
This text is portaled at the end of document.body!
</Portal>
<Portal node={document && document.getElementById('youCanSelectAnyIdFromTheDOM')}>
This text is portaled into San Francisco!
</Portal>
You can read more about react-portal Here

How to use bootstrap with reactjs

I'm a newbie in React.js and since I began to read documents and tutorials, I am not sure how does Bootstrap work with React.js.
I saw a couple of npm packages such as reactstrap or react-bootstrap, however, I don't get it. The HTML code comes from a method that returns a piece of HTML (like this):
class App extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
If I'm right...
So, my question is either:
Should I add the <link/> or <script/> of Bootstrap into index.html, either into body or into header?
or
Do I have to include Bootstrap from my App.js file and use it from a method?
PS: I am developing for years now but I never did any Javascript/HTML/CSS web, so if you have any advice, thanks in advance!
I need to use the logic of Bootstrap grid in order to realize an HCI
Thanks for any help
To answer your question, both of your suggestions on your questions are correct. You can do it either way.
Include bootstrap CDN in your index.html
You can add bootstrap packages such as React-Bootstrap using npm/yarn and import required components into you App.js
If you do it first way all you need to do is add your Bootstrap CDN in index.html and when you access your class in Javascript, it will be working fine
NOTE: While accessing class in react use className and not class
Here is an example of how you add CDN in your index.html
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: ''
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({
value: event.target.value
});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<div>
<form onSubmit = {this.handleSubmit} >
<label>
Name:
</label>
<input type = "text" className="form-control"
value = {this.state.value}
onChange = {this.handleChange}/>
<input type = "submit"
value = "Submit" className="btn btn-primary"/>
</form>
</div>
);
}
}
ReactDOM.render( < App / > , document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<div id='root'></div>
EDIT:-
Assuming you installed React according to Official Installation
Use the following file structure
index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/style/style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
<!-- And then your bundled js -->
</head>
<body>
<div class="container"></div>
</body>
<script src="/bundle.js"></script>
</html>
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/app'; //Make sure it's the path to your App.js
ReactDOM.render(
<App />
, document.querySelector('.container'));
src/components/app.js
import React, { Component } from 'react';
export default class App extends Component {
render() {
return (
<div>
<form onSubmit = {this.handleSubmit} >
<label>
Name:
</label>
<input type = "text" className="form-control"
value = {this.state.value}
onChange = {this.handleChange}/>
<input type = "submit"
value = "Submit" className="btn btn-primary"/>
</form>
</div>
);
}
}
Check this, it should work.