I am having trouble with my UserInfo component and User.name and User.email console.logs not showing up on my React page and console. When I check the console, it says "Loading failed for the with source “http://127.0.0.1:5501/public/%PUBLIC_URL%/index.js”," and the same goes for the app.js file. I am new to React and I am not sure what I am doing wrong. I would really appreciate any help, as I am still learning and trying to improve my skills in this framework. Thank you for your time.
Regenerate response
import React from 'react';
import { Container, Row, Col, Image, ListGroup, ListGroupItem } from 'react-bootstrap';
// This is the App component which will be the main component of the application.
function App() {
return (
// The App component will render two other components, the App component itself and the UserInfo component.
<div className="App">
<App />
<UserInfo />
</div>
);
}
// This is the user object which will hold the information about a user.
const User = {
name: "John",
surname: "Doe",
date_of_birth: "01/01/1980",
address: "123 Main Street",
country: "USA",
email: "john.doe#email.com",
telephone: "555-555-5555",
company: "Acme Inc.",
profilePicture: "https://example.com/profile_ picture.jpg",
shoppingCart: [
{ item: "T-Shirt", quantity: 2, price: 20 },
{ item: "Jeans", quantity: 1, price: 50 },
{ item: "Sneakers", quantity: 1, price: 80 }
]
};
// This is the UserInfo component which will display the user information.
function UserInfo() {
// Log the user's name and email to the console.
console.log("User name: ", User.name);
console.log("User email: ", User.email);
return (
// The UserInfo component will use Bootstrap's container, row, and column components to format the user's information.
<Container className="user-info-container">
<Row>
<Col xs={12} md={4}>
// The user's profile picture will be displayed using the Image component from react-bootstrap.
<Image src={User.profilePicture} rounded className="profile-picture" />
</Col>
<Col xs={12} md={8}>
// The user's name will be displayed in an h2 header.
<h2>{User.name} {User.surname}</h2>
// The user's information will be displayed in a list group using the ListGroup and ListGroupItem components from react-bootstrap.
<ListGroup className="user-details">
<ListGroupItem>Date of Birth: {User.date_of_birth}</ListGroupItem>
<ListGroupItem>Address: {User.address}</ListGroupItem>
<ListGroupItem>Country: {User.country}</ListGroupItem>
<ListGroupItem>Email: {User.email}</ListGroupItem>
<ListGroupItem>Telephone: {User.telephone}</ListGroupItem>
<ListGroupItem>Company: {User.company}</ListGroupItem>
</ListGroup>
</Col>
</Row>
</Container>
);
}
// Export the App component as the default export.
export default App;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<script src="%PUBLIC_URL%/index.js"></script>
<script src="%PUBLIC_URL%/App.js"></script>
<div id="root">
<App />
</div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Everything is fine with react code itself (except trying to render App component inside App component). Just try to create a fresh project and past your code there.
You can check it in the sandbox example with your code: codesandbox.io
Related
Im trying to learn react and next js. I wanna use this plugin. I installed that with npm but i dont know how to import it.
How i'm gonna use npm installed packages in my code?
Here is the code...
import React from 'react';
import VirtualSelect from 'virtual-select-plugin';
function Options() {
VirtualSelect.init({
ele: '#sample-select',
options: [
{ label: 'Options 1', value: '1' },
{ label: 'Options 2', value: '2' },
{ label: 'Options 3', value: '3' },
],
});
return <div className='container mx-auto lg:px-10 px-5 mt-10'>
<h2>Options</h2>
<div>
<div>
<h3>Genre</h3>
<div id="sample-select"></div>
</div>
<div>
<h3>Year</h3>
</div>
<div>
<h3>Seasons</h3>
</div>
</div>
</div>;
}
export default Options;
error message:
./components/Options.js:2:0
Module not found: Can't resolve 'virtual-select-plugin'
1 | import React from 'react';
> 2 | import VirtualSelect from 'virtual-select-plugin';
3 |
4 | function Options() {
5 |
Import trace for requested module:
./pages/index.js
https://nextjs.org/docs/messages/module-not-found
<link rel="stylesheet" href="node_modules/virtual-select-plugin/dist/virtual-select.min.css">
<script src="node_modules/virtual-select-plugin/dist/virtual-select.min.js"></script>
<!-- optional -->
<link rel="stylesheet" href="node_modules/tooltip-plugin/dist/tooltip.min.css">
<script src="node_modules/tooltip-plugin/dist/tooltip.min.js"></script>
This is from the docs of virtual-select-plugins
Reference
and you said you're using next js there is a scripttag in Nextjs Put it on your whole application _app.js in pages
_app.js Reference
I suggest read the docs
there are many ways to do that
first option is to add your script tag in the public html page
second option is to install react helemet package for adding an element of the head of component https://www.npmjs.com/package/react-helmet
or you can simply use this package to create a virtual select in react https://www.npmjs.com/package/react-select-virtualized
I think you can resolve this simply by npm install.
Install the required package.
$ npm i virtual-select-plugin
Then you can see virtual-select-plugin module is added to dependencies. Look at package.json.
{
"dependencies":{
...
"virtual-select-plugin": "^1.0.29",
...
}
}
I am having issues with wrapPageElement in my Gatsby 4 project.
wrapPageElement.js
import React from 'react';
import { PathProvider } from './src/providers/path';
import Layout from './src/components/layout/layout';
// Pass all props (hence the ...props)
// to the layout component so it has access to things like pageContext or location
const wrapPageElement = ({ element, props: { location } }) => (
<PathProvider path={location.pathname}>
<Layout>{element}</Layout>
</PathProvider>
);
export default wrapPageElement;
I am using wrapPageElement to reuse my Layout across all pages but the Layout does not update its React state properly when included via wrapPageElement. If I render Layout within my pages instead, it works fine.
gatsby-brower.js
import './src/styles/global.css';
import CustomProviders from './wrapWithProvider';
import CustomLayout from './wrapPageElement';
export const wrapPageElement = CustomLayout;
export const wrapRootElement = CustomProviders;
A view components down in my navbar within Layout I am calling:
const { language, defaultLanguage } = useI18next();
console.log('locale', language);
When I am changing my page language with I18next, "locale" does not change value. "locale" does however change its value to the updated language if I am rendering the layout within my page.
I should note that I am using TypeScript for all of my project except the Gatsby lifecycle files, e.g. wrapPageElement.js
Any help is appreciated! Not sure where exactly the root cause could be at?
Additional code
Layout component
return (
<div className="page">
<Helmet>
<meta httpEquiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=0" />
<meta name="description" content={props.description || description} />
<meta name="image" content={props.imagePath || image} />
<title>{props.title || title}</title>
{props.noIndex && <meta name="robots" content="noindex" />}
</Helmet>
<Navbar />
<main className="m-10 mt-60">{children}</main>
<Footer />
</div>
);
};
Navbar component
return (
<nav className="bg-green-300 w-full fixed top-0">
<ul className="flex flex-row gap-5 m-10">
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li className="ml-auto">
<ChangeLanguageLink language="en">EN</ChangeLanguageLink>
</li>
<li>
<ChangeLanguageLink language="th">TH</ChangeLanguageLink>
</li>
</ul>
</nav>
);
ChangeLanguageLink component
const ChangeLanguageLink: React.FC<React.PropsWithChildren<ChangeLanguageLinkProps>> = ({ children, ...props }) => {
const { originalPath } = useI18next();
return (
<LocalizedLink {...props} to={addFinalSlash(originalPath)}>
{children}
</LocalizedLink>
);
};
What I extract is that you are trying to use I18next to update the state but you may not need to wrap your whole application to achieve that. The const { language, defaultLanguage } = useI18next(); will give you the current language.
That said, if you keep wanting your approach, wrapPageElement and wrapRootElement are wrappers (hence the name) that are shared between Gatsby SSR and Gatsby Browser so in the gatsby-ssr.js you need to add the exact information:
import CustomProviders from './wrapWithProvider';
import CustomLayout from './wrapPageElement';
export const wrapPageElement = CustomLayout;
export const wrapRootElement = CustomProviders;
Keep in mind that wrapRootElement is a wrapper that is never unmounted across the application.
I'm trying to pass data from Express backend to React frontend with Axios, but It doesn't work. The data I'm trying to pass comes from a text file.
Backend:
const express = require('express');
const app = express();
var fs = require('fs')
var data1 = fs.readFileSync('./inputs/category1.txt', 'utf8')
var textByLine1 = data1.split('\r\n')
var data2 = fs.readFileSync('./inputs/category2.txt', 'utf8')
var textByLine2 = data2.split('\n')
console.log(textByLine1)
app.get("/", function(req, res){
res.send(textByLine1)
})
app.listen(3001, function(){
console.log("express server is running on port 3001");
})
Axios:
import axios from 'axios';
export type ApiClient = {
getProperties: (c:number) => Promise<string[]>;
}
/** get tickets with search and page queries */
export const createApiClient = (): ApiClient => {
return {
getProperties: async (c:number) => {
const res = await axios.get('/', { params: { category: c} });
return res.data;
}
}
}
export default createApiClient
React frontend:
import React from 'react';
import './App.css';
import {createApiClient} from './api'; //connection to server
export type AppState = {
flow: number,
category_index: number,
categories: string[],
}
const api = createApiClient()
export class App extends React.PureComponent<{}, AppState> {
state: AppState = {
flow: 1,
category_index: 2,
categories:[]
}
async componentDidMount() {
this.setState({
categories: await api.getProperties(this.state.flow)
});
console.log(this.state.categories)
}
render() {
return(
<main>
<div>
<button>click me</button>
</div>
</main>
)
}
}
export default App;
I'm trying to pass the list of strings from the backend to the frontend, than console.log it to see that it was actually passed. instead, I see the following in the console:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="/manifest.json" />
<!--
Notice the use of in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script src="/static/js/bundle.js"></script><script src="/static/js/vendors~main.chunk.js"></script><script src="/static/js/main.chunk.js"></script></body>
</html>
I think that means I'm getting "empty" in the axios.get(). What am I doing wrong?
To call your API, you’ll need to call the URL that your API is serving, which I believe is http://localhost:3001/.
Try this:
const res = await axios.get('http://localhost:3001/', { params: { category: c} });
I'm trying to add a clucth.co widget to a Gatsby site, but it does not render. I've tried using react Helmet for the <script> part, but it still does not work.
Hopefully I'm missing something simple here, but looking at other solutions I can't find anything that works.
For reference: https://clutch.co/content/add-review-widget-your-website
<script type="text/javascript" src="https://widget.clutch.co/static/js/widget.js"></script>
<div className="clutch-widget" data-url="https://widget.clutch.co" data-widget-type="7" data-height="65" data-clutchcompany-id="XXXXXXX"></div>
You have multiple ways of inserting a third-party script in Gatsby. The problem you'll face in all of them is that you need to await that your div:
<div className="clutch-widget" data-url="https://widget.clutch.co" data-widget-type="7" data-height="65" data-clutchcompany-id="XXXXXXX"></div>
Needs to be rendered your script won't be able to load.
Using Script component (2022 update)
Since the release of the Script Gatsby component (powered by Partytown) it's much easier adding third-party scripts. Just:
import React from "react"
import { Script } from "gatsby"
function YourPage() {
return <Script src="https://my-example-script" />
}
export default YourPage
Using Helmet:
You said you already tried but it should. You may need to try the drop-in support that adds the gatsby-plugin-react-helmet. Then:
<Layout>
<SEO title="Live" />
<Helmet>
<script src="https://tlk.io/embed.js" type="text/javascript"/>
</Helmet>
</Layout>
Check the compatibility issues when used with hooks.
Using onRenderBody API from gatsby-ssr.js:
Gatsby exposes a setHeadComponents function in the onRenderBodyAPI that you can take advantage from:
import React from "react"
export const onRenderBody = ({ setHeadComponents }, pluginOptions) => {
setHeadComponents([
<script key="tracking"
src="https://widget.clutch.co/static/js/widget.js
type="text/javascript"
async
/>,
])
}
This snippet above will insert the <script> in the <head> tag of the compiled HTML.
Here you have another approach using dangerouslySetInnerHTML:
setHeadComponents([
<script dangerouslySetInnerHTML={{whateveryouneedtoset}}>
])
Extracted from Unable to Inject 3rd Party Scripts in Gatsby
Modifying directly the html.js:
You can customize even more the output of the resultant HTML by modifying the html.js, the boilerplate that uses Gatsby to build your entire site.
Run:
cp .cache/default-html.js src/html.js
Or alternatively, copy the default-html.js from .cache folder into /src and rename it to html.js. When compiling, if the html.js is present, Gatsby will take it to build your site based on that skeleton.
You'll have something like:
import React from "react"
import PropTypes from "prop-types"
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
There you can add your <script> directly:
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<script type="text/javascript" src="https://widget.clutch.co/static/js/widget.js"></script>
{props.headComponents}
</head>
Using gatsby-plugin-load-script:
Just install and use the plugin:
{
resolve: 'gatsby-plugin-load-script',
options: {
src: 'https://widget.clutch.co/static/js/widget.js',
},
},
Hacking the gatsby-browser.js API:
If none of the above fits you, you can still use one of gatsby-browser.js APIs (onClientEntry) to manually add script given a source URL:
const addScript = url => {
const script = document.createElement("script")
script.src = url
script.async = true
document.body.appendChild(script)
}
export const onClientEntry = () => {
window.onload = () => {
addScript("https://widget.clutch.co/static/js/widget.js")
}
}
In order to not have the clutch widget disappear on route changes, I ended up running the Init and Destroy methods from window.CLUTCHCO myself in useEffect.
React.useEffect(() => {
// add widget to end of body and run it
const script = document.createElement("script")
script.type = "text/javascript"
script.src = "https://widget.clutch.co/static/js/widget.js"
script.async = true
document.body.appendChild(script)
// run script
script.onload = () => {
// #ts-expect-error Apparently we have to manually do this!! 🗑️
// eslint-disable-next-line #typescript-eslint/no-unsafe-member-access, #typescript-eslint/no-unsafe-call
window.CLUTCHCO.Init()
}
return () => {
// #ts-expect-error Apparently we have to manually do this!! 🗑️
// eslint-disable-next-line #typescript-eslint/no-unsafe-member-access, #typescript-eslint/no-unsafe-call
window.CLUTCHCO.Destroy()
document.body.removeChild(script)
}
}, [])
I'm trying to get my nav bar to change depending on which page the app is on without having to create individual nav components for each page. I want the nav bar to change once the user goes to a new 'projects' page. The way I would do this is to conditionally render the nav bar elements depending on the url parameter. Once the user clicks to go to the project page, there will be a url parameter such as localhost/project/movie. However, the nav bar component does not have access to the match.params.projectId, only the project page component has access to it since it's within a Route component from react-router. Therefore, I want to make a global state that stores the url parameter so that I could use it within the navbar component to conditionally render the elements of that component.
Highest level App component
const App = () => {
return (
<div className="app">
<Header/>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/project/:projectId" component={ProjectOverview}/>
</Switch>
</div>
);
}
Lower level Project page component
const ProjectOverview = ({ match }) => {
useEffect(() => {
window.scrollTo(0, 650);
}, []);
let project = {};
if(match.params.projectId === 'movie'){
project = {
p: 'Browse your favorite Movies, TV shows, and actors. Search for specific movies, shows or actors by date, rating, region and other categories. Browse the latest and greatest films and to find information about its actors, crew, and reviews. Rate and favorite Movies, TV shows and actors while having access to them through a user account. Login / Authentication.',
img: 'http://www.technologies.com/images/cloud-summary.png',
gif: 'https://giphy.com/media/mUgG6FZuWN9V1/giphy.gif',
list: ['React', 'Redux', 'Hooks', 'TMDB API', 'Sass', 'React Router']
}
} else if(match.params.projectId === 'ecommerce'){
project = {
p: 'Something else',
img: 'http://www.technologies.com/images/cloud-summary.png',
gif: 'https://giphy.com/media/IgASZuWN9V1/giphy.gif',
list: ['React', 'Redux', 'Hooks', 'TMDB API', 'Sass', 'React Router']
}
}
return(
I know the provider has to wrap around the header(navbar) component within the app component but the state value that is needed (match.params.projectId) can only be found within the project page component. I'm wondering how I could get the value for the provider to be whatever the url parameter is within the project page component. I will try to further clarify my question if it seems too confusing for anyone. Thank you
I don't know if it is the best solution, but in an application where I had to change the nav's title depending on the route I did the following:
function App() {
const [title, setTitle] = useState('');
return <Router>
<Navbar title={title} />
<Switch>
<Route path="/product/:id" exact render={props => <ProductPage {...props} setTitle={setTitle} />} />
</Switch>
</Router>
}
And in the ProductComponent:
function ProductionComponet({setTitle, match}){
useEffect(()=>{
setTitle(`product ${match.params.id}!`)
},[])
}