I have the following js
App.js
<LayoutRoute
exact
path="/analysis/:id"
layout={MainLayout}
component={AnalysisPage}
/>
index.js
<IconWidget
title="companyA"
subtitle="Top Product Trade: Pen"
color="info"
onClick={()=>{window.location='analysis/companyA'}}
/>
analysis.js
function analysisPage({match}){
console.log(match)
return(
<div>
{"${match.params.id}"}
</div>
)
}
const AnalysisPage= () => {
return(
<div>
Company: {this.analysisPage}
</div>
export default AnalysisPage;
I have applied react router in the App.js which can redirect the website from index.js to analysis.js by pressing the button.
However, I would like to display the params to the div. I took reference from https://alligator.io/react/react-router-parameters however, it doesn't work. I would like to know what have I did wrong? Thank you so much
You have to provide the props:
Company: {this.analysisPage(this.props)}
So that match params could be used:
function analysisPage({match}){
You can try this
this.props.match.params.id
Related
I have the following structure of the code:
router.js:
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'App',
component: () => import('../../src/App.vue'),
},
{
path: '/:pathMatch(.*)',
name: 'ErrorView',
component: () => import('../components/Error.vue'),
}
],
});
export default router;
App.vue
<template>
<Land />
<LeftNavbar />
<Navbar />
<Experience />
<TechnologiesCarousel />
<Projects />
<Copyright />
<BackToTop />
</template>
When I'm pressing in the URL bar: http://localhost:3000. The app is rendering properly which is fine, but when I'm trying to write a wrong URL, for eg: http://localhost:3000/abcf/ || http://localhost:3000/dsafbdmhgfjweghjfw to be redirected to the 404 page, I'm not redirected, the page still rendering the App.vue component.
Does anyone have any idea why the 404 page isn't rendered?
Try like following /:pathMatch(.*)*:
{
path: "/:pathMatch(.*)*",
name: 'ErrorView',
component: () => import('../components/Error.vue'),
},
and in App.vue place <router-view /> and move components to other view.
I assume you are using Vue 3.
In your router file you need to change the path to this:
{
path: '/:pathMatch(.*)*',
name: 'ErrorView',
component: () => import('../components/Error.vue'),
}
For Vue 2 the path can be: path:'*'
From Vue 2 -> 3 migration some more info for those they want to know what has changed:
Essentially, you should be able to replace the '' path with '/:pathMatch(.)*' and be good to go!
Reason: Vue Router doesn't use path-to-regexp anymore, instead it implements its own parsing system that allows route ranking and enables dynamic routing. Since we usually add one single catch-all route per project, there is no big benefit in supporting a special syntax for *.
In my Next.js project I have a script that renders a widget as follows:
<a
className="e-widget no-button xdga generic-loader"
href="https://example"
rel="nofollow"
>
3 lucky winners stand a chance to win…
</a>
<Script
type="text/javascript"
src="https://widget.gleamjs.io/e.js"
strategy="afterInteractive"
></Script>
The problem is that once this script executes on the initial render, it does not execute again later.
Anyone know how I can get the script to execute multiple times?
The issue might be originating from other parts but you can give this a shot:
import React, { FC } from "react";
import Script from "next/script";
interface Props {
id: string;
}
const Widget: FC<Props> = ({ id }) => {
return (
<>
<a
className="e-widget no-button xdga generic-loader"
href="https://example"
rel="nofollow"
>
3 lucky winners stand a chance to win…
</a>
<Script
id={id}
src="https://widget.gleamjs.io/e.js"
strategy="afterInteractive"
/>
</>
);
};
export default Widget;
I managed to solve the problem by forcing the parent component to re-mount, which then causes my Script tag to re execute/render as desired.
I keep getting this weird error in my React that says
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `ContactTemplate`.
I tried to remove each of the import to see where the error is, but nothing works.
My ContactTemplate.jsx:
import React from 'react';
import { Container } from '~/components/interface/Container';
import PreviewBar from '~/components/PreviewBar';
import HeroFull from '~/components/HeroFull/HeroFull';
import { Wrapper, Columns, Paragraph, BigText } from './ContactTemplate.styles';
import { Link } from '~/components/interface/Link';
const ContactTemplate = ({ preview }) => {
const data = [
{
name: 'Name 1',
job: 'Bestuursrechts',
phone: '+31 (0) 612345678',
email: 'Email',
link: 'https://www.linkedin.com',
},
{
name: 'Name 2',
job: 'Intellectuele eigendom en contractenrecht',
phone: '+31 (0) 612345678',
email: 'email',
link: 'https://www.linkedin.com',
},
];
return (
<>
<Wrapper>
{preview && <PreviewBar />}
<HeroFull
title="Contact"
intro="We offer ...."
/>
</Wrapper>
<Container>
<Columns>
{data.map(item => (
<div>
<BigText>{item.name}</BigText>
<Paragraph>{item.job}</Paragraph>
<Paragraph>{item.phone}</Paragraph>
<Paragraph>{item.email}</Paragraph>
<Link>{item.link}</Link>
</div>
))}
</Columns>
</Container>
</>
);
};
export default ContactTemplate;
Could someone help me out with this please?
If there are more files needed I'll add them on request.
Most likely you're trying to import { ContactTemplate } from "./ContactTemplate", but you're using export default. At this point you should import ContactTemplate from "./ContactTemplate"
Can you confirm if this is the case?
Can you show the component, where you import and trying to use ContactTemplate?
I solved it myself. The first problem was that my Docker was stuck so I had to restart it. After I restarted it I tried to remove each import individually to see where the problem was and it was the { Link } that needed to be just Link. Thanks everyone else for helping!
I would like to make an articles system on my site created with React, but I'm a bit lost.
I have a JS array that allows me to make a loop to display my articles. When I click on an article, it sends me to the right page thanks to the <Link />. But here is my problem, how to display the content of the article I clicked on? I tried to get the slug of the article and to compare it to the ID of the elements of my array but I have to admit that I don't know where I stand.
Here is my code, it only returns a <h1>Title: { id }</h1> (which is the correct slug every time)
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams
} from "react-router-dom";
import '../styles/Single.css'
const posts = [
{
source:
"./images/esdexp-th-homepage.jpg",
content: {
name: "Expérience ESD",
link:"/post/ESDexp",
idSlug :"ESDexp"
}
},
{
source:
"./images/vacui-th-homepage.jpg",
content: {
name: "Horror Vacui",
link:"/post/horrorvacui",
idSlug : "horrorvacui"
}
},
{
source:
"./images/meteo-th-homepage.jpg",
name: "Forecast",
link:"/post/forecast",
idSlug :"forecast"
},
{
source:
"./images/ami-th-homepage.jpg",
name: "Citroën Ami",
link:"/post/ami",
idSlug :"ami"
},
{
source:
"./images/musee-th-homepage.jpg",
content: {
name: "Musée Home",
link:"/post/musee",
idSlug :"musee"
}
},
];
export default function ParamsExample() {
return (
<Router>
<Switch>
<Route path="/post/:id" children={<Child />} />
</Switch>
</Router>
);
}
function Child() {
let { id } = useParams();
console.log({id})
var itemPost = posts.filter(function(displayPost) {
return displayPost.idSlug == { id };
});
console.log(itemPost)
return (
<div>
<div className="single-container rev-block">
<div className="single-content-container">
<h1>Title : {id}</h1>
</div>
</div>
</div>
);
}
I hope I've made this as clear as possible,
Thanks in advance!
It is not working because the posts data is not consistent. The idSlug of some posts are inside the content object.
To handle that situation you have to check if the idSlug is not undefined, and if it is, set the post slug or ID to use the idSlug inside the content object.
A working example can be found here.
Sandbox: https://codesandbox.io/s/angry-cannon-7kxiz?file=/src/App.js
The useParams has been replaced with an actual ID or slug of a post because the sandbox does not allow routing.
This line handles the inconsistency of the posts data.
let post_slug = displayPost.idSlug
? displayPost.idSlug
: displayPost.content.idSlug;
Also, please note that filter returns another array, so you have to access post or the itemPost using the first index.
<h1>Title : {itemPost[0].content.name}</h1>
And of course, you can also use the id returned by the useParams.
try this.
function Child() {
let { id } = useParams();
console.log({id})
var itemPost = posts.filter(function(displayPost) {
return displayPost.idSlug === id ; // you don't need those curly braces.
});
console.log(itemPost)
return (
<div>
<div className="single-container rev-block">
<div className="single-content-container">
<h1>Title : {id}</h1>
</div>
</div>
</div>
);
}
Get the help of <Link /> to pass the state from parent component to child component. Make the parent component like this:
<Link to={{
pathname:{'/post/post.id'},
state:{
post:post
}
}}>
Then you can get the post in the child component as below:
function child(props){
const post = props.location.state.post
}
Also, try to make the routing as below. It won't make much complications:
<Route path="/post/:id" component={Child} />
I am building a website using React, and I want to integrate a shop from spreadshop.com / spreadshirt.com, to my React website.
Spreadshop.com gives quite good instructions on how to use script-tags to integrate their shop to an html-site (instructions can be found here).
I am not an experienced programmer, and I'm a little confused about how scripts work with React and especially about where I should put the spread_shop_config, which the Spreadshop instructions tells me to have available in window Scope. I have tried to use a useScript-hook, which I found here. But it doesn't seem to work.
Below is my implementation attempt so far.
What am I doing wrong? How can I integrate the Spreadshirt shop to my React website?
import React from 'react';
import useScript from './Hooks/useScript';
function Shop() {
const [loaded, error] = useScript('https://shop.spreadshirt.no/shopfiles/shopclient/shopclient.nocache.js');
var spread_shop_config = {
shopName: 'awesome-merch-shop',
locale: 'US',
prefix: 'https://shop.spreadshirt.com',
baseId: 'shop'
}
return (
<div className="shopBody">
{loaded && !error && (
<div id="shop">
<div>
<i id="spinner" className="fa fa-spinner" aria-hidden="true"/>
<p>Loading The Shop...</p>
</div>
</div>
)}
</div>
);
}
export default Shop;
I'll answer myself here, since I figured a better way and which actually works (better) for all scripts even if you need to add multiple different scripts to a page/component.
(Now I'm actually confused why we need a useScript-hook at all).
Inside the react component that needs to use the script, it seems better to use javascript to create a script-element and then append it to the document.body.
So in example, to add the Spreadshop.com script inside the Shop-component:
import React from 'react';
import './Shop.css';
function Shop() {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = "https://shop.spreadshirt.no/shopfiles/shopclient/shopclient.nocache.js";
document.body.appendChild(js);
return (
<div className="shopBody">
<div id="shop">
<i id="spinner" className="fa fa-spinner" aria-hidden="true"/>
<p>Loading The Shop...</p>
</div>
</div>
);
}
export default Shop;
And the Spreadshop configurations variable I just add normally with script tags inside the index.html in the publics folder.
<script>
var spread_shop_config = {
shopName: 'awesome-merch-shop',
locale: 'US',
prefix: 'https://shop.spreadshirt.com',
baseId: 'shop'
}
</script>
By doing it this way, the Spreadshop script won't give an error message when loading every component, because the script is only appended when that component loads.
And also, since the script is loaded whenever that component is loaded, it will work even if you refresh the page, while if the script was only in the index.html then the index.html would have to be loaded for the script to be loaded.
Include the javascript and Spreadshirt config in your high-level index.js file. For most it's something like /public/index.html (the same folder you have your manifest.json, robots.txt, etc) along with my google fonts and bootstrap include before </html>
For my implementation I added
<script>
var spread_shop_config = {
shopName: 'YourShopNameHere',
locale: 'us_US',
prefix: 'https://shop.spreadshirt.com',
baseId: 'myShop'
};
</script>
<script type="text/javascript" src="https://shop.spreadshirt.com/shopfiles/shopclient/shopclient.nocache.js"></script>
And then in the React component:
import React from 'react';
import './Shop.css';
type Props = {
testProp: string
};
export const Shop = ({ testProp }: Props) => {
return (
<div id="Shop-Component">
<div id="myShop">
<div>is loading text here...</div>
</div>
</div>
);
};
export default(Shop);