Hi i am unable to see the image ,i have rendered it in menu component as below and atattched the screenshot,can sommeone see whats the problem,my images folder is in public folder, Hi i am unable to see the image ,i have rendered it in menu component as below and attached the screenshot,can sommeone see whats the problem,my images folder is in public folder
import React, { useState } from 'react';
import Menu from './Menu';
import Categories from './Categories';
import items from './data';
function App() {
const [menuItems ,setMenuItems] = useState(items)
const [categories,setCategories] = useState([])
const filterItems = (category) => {
if(category === "all"){
setMenuItems(items)
return;
}
const newItems = items.filter((item) => item.category === category)
setMenuItems(newItems)
}
return <main>
<section className="menu section">
<div className="title">
<h2>Menu</h2>
<div className="underline"></div>
</div>
<Categories categories = {categories} filterItems ={filterItems} />
<Menu items={menuItems}/>
</section>
</main>;
}
export default App;
import React from 'react';
const Menu = ({items}) => {
return(<div className = "section-center">
{items.map((menuItem) => {
const {id,title,img,desc,price} = menuItem;
return (<article key ={id} className = "menu-item">
<img src = {img} alt = {title} className = "photo"></img>
<div className="item-info">
<header>
<h4>{title}</h4>
<h4 className="price">${price}</h4>
</header>
<p className = "item-text">{desc}</p>
</div>
</article>)
})}
</div>)}
export default Menu;
import React from 'react'
const Categories= ({filterItems}) => {
return(
<div className='btn-container'>
<button className='filter-btn' onClick={() => filterItems( 'all' )}>All</button>
<button className='filter-btn' onClick={() => filterItems( 'breakfast' )}>Breakfast</button>
<button className='filter-btn' onClick={() => filterItems( 'lunch' )}>Lunch</button>
<button className='filter-btn' onClick={() => filterItems( 'shakes' )}>Shakes</button>
</div>
)
}
export default Categories
const menu = [
{
id: 1,
title: 'buttermilk pancakes',
category: 'breakfast',
price: 15.99,
img: './images/item-1.jpeg',
desc: `I'm baby woke mlkshk wolf bitters live-edge blue bottle, hammock freegan copper mug whatever cold-pressed `,
},
{
id: 2,
title: 'diner double',
category: 'lunch',
price: 13.99,
img: './images/item-2.jpeg',
desc: `vaporware iPhone mumblecore selvage raw denim slow-carb leggings gochujang helvetica man braid jianbing. Marfa thundercats `,
},
{
id: 3,
title: 'godzilla milkshake',
category: 'shakes',
price: 6.99,
img: './images/item-3.jpeg',
desc: `ombucha chillwave fanny pack 3 wolf moon street art photo booth before they sold out organic viral.`,
},
{
id: 4,
title: 'country delight',
category: 'breakfast',
price: 20.99,
img: './images/item-4.jpeg',
desc: `Shabby chic keffiyeh neutra snackwave pork belly shoreditch. Prism austin mlkshk truffaut, `,
},
{
id: 5,
title: 'egg attack',
category: 'lunch',
price: 22.99,
img: './images/item-5.jpeg',
desc: `franzen vegan pabst bicycle rights kickstarter pinterest meditation farm-to-table 90's pop-up `,
},
{
id: 6,
title: 'oreo dream',
category: 'shakes',
price: 18.99,
img: './images/item-6.jpeg',
desc: `Portland chicharrones ethical edison bulb, palo santo craft beer chia heirloom iPhone everyday`,
},
{
id: 7,
title: 'bacon overflow',
category: 'breakfast',
price: 8.99,
img: './images/item-7.jpeg',
desc: `carry jianbing normcore freegan. Viral single-origin coffee live-edge, pork belly cloud bread iceland put a bird `,
},
{
id: 8,
title: 'american classic',
category: 'lunch',
price: 12.99,
img: './images/item-8.jpeg',
desc: `on it tumblr kickstarter thundercats migas everyday carry squid palo santo leggings. Food truck truffaut `,
},
{
id: 9,
title: 'quarantine buddy',
category: 'shakes',
price: 16.99,
img: './images/item-9.jpeg',
desc: `skateboard fam synth authentic semiotics. Live-edge lyft af, edison bulb yuccie crucifix microdosing.`,
},
];
export default menu;
<!-- language: lang-css -->
/*
===============
Variables
===============
*/
:root {
/* dark shades of primary color*/
--clr-primary-1: hsl(205, 86%, 17%);
--clr-primary-2: hsl(205, 77%, 27%);
--clr-primary-3: hsl(205, 72%, 37%);
--clr-primary-4: hsl(205, 63%, 48%);
/* primary/main color */
--clr-primary-5: hsl(205, 78%, 60%);
/* lighter shades of primary color */
--clr-primary-6: hsl(205, 89%, 70%);
--clr-primary-7: hsl(205, 90%, 76%);
--clr-primary-8: hsl(205, 86%, 81%);
--clr-primary-9: hsl(205, 90%, 88%);
--clr-primary-10: hsl(205, 100%, 96%);
/* darkest grey - used for headings */
--clr-grey-1: hsl(209, 61%, 16%);
--clr-grey-2: hsl(211, 39%, 23%);
--clr-grey-3: hsl(209, 34%, 30%);
--clr-grey-4: hsl(209, 28%, 39%);
/* grey used for paragraphs */
--clr-grey-5: hsl(210, 22%, 49%);
--clr-grey-6: hsl(209, 23%, 60%);
--clr-grey-7: hsl(211, 27%, 70%);
--clr-grey-8: hsl(210, 31%, 80%);
--clr-grey-9: hsl(212, 33%, 89%);
--clr-grey-10: hsl(210, 36%, 96%);
--clr-white: #fff;
--clr-gold: #c59d5f;
--clr-red-dark: hsl(360, 67%, 44%);
--clr-red-light: hsl(360, 71%, 66%);
--clr-green-dark: hsl(125, 67%, 44%);
--clr-green-light: hsl(125, 71%, 66%);
--clr-black: #222;
--transition: all 0.3s linear;
--spacing: 0.1rem;
--radius: 0.25rem;
--light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
--dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
--max-width: 1170px;
--fixed-width: 620px;
}
/*
===============
Global Styles
===============
*/
*,
::after,
::before {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background: var(--clr-grey-10);
color: var(--clr-grey-1);
line-height: 1.5;
font-size: 0.875rem;
}
ul {
list-style-type: none;
}
a {
text-decoration: none;
}
h1,
h2,
h3,
h4 {
letter-spacing: var(--spacing);
text-transform: capitalize;
line-height: 1.25;
margin-bottom: 0.75rem;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.25rem;
}
h4 {
font-size: 0.875rem;
}
p {
margin-bottom: 1.25rem;
color: var(--clr-grey-5);
}
@media screen and (min-width: 800px) {
h1 {
font-size: 4rem;
}
h2 {
font-size: 2.5rem;
}
h3 {
font-size: 1.75rem;
}
h4 {
font-size: 1rem;
}
body {
font-size: 1rem;
}
h1,
h2,
h3,
h4 {
line-height: 1;
}
}
/* global classes */
/* section */
.section {
width: 90vw;
margin: 0 auto;
max-width: var(--max-width);
}
@media screen and (min-width: 992px) {
.section {
width: 95vw;
}
}
/*
===============
Menu
===============
*/
.menu {
padding: 5rem 0;
}
.title {
text-align: center;
margin-bottom: 2rem;
}
.underline {
width: 5rem;
height: 0.25rem;
background: var(--clr-gold);
margin-left: auto;
margin-right: auto;
}
.btn-container {
margin-bottom: 4rem;
display: flex;
justify-content: center;
}
.filter-btn {
background: transparent;
border-color: transparent;
font-size: 1rem;
text-transform: capitalize;
margin: 0 0.5rem;
letter-spacing: 1px;
padding: 0.375rem 0.75rem;
color: var(--clr-gold);
cursor: pointer;
transition: var(--transition);
border-radius: var(--radius);
}
.filter-btn:hover {
background: var(--clr-gold);
color: var(--clr-white);
}
.section-center {
width: 90vw;
margin: 0 auto;
max-width: 1170px;
display: grid;
gap: 3rem 2rem;
justify-items: center;
}
.menu-item {
display: grid;
gap: 1rem 2rem;
max-width: 25rem;
}
.photo {
object-fit: cover;
height: 200px;
width: 100%;
border: 0.25rem solid var(--clr-gold);
border-radius: var(--radius);
display: block;
}
.item-info header {
display: flex;
justify-content: space-between;
border-bottom: 0.5px dotted var(--clr-grey-5);
}
.item-info h4 {
margin-bottom: 0.5rem;
}
.price {
color: var(--clr-gold);
}
.item-text {
margin-bottom: 0;
padding-top: 1rem;
}
@media screen and (min-width: 768px) {
.menu-item {
grid-template-columns: 225px 1fr;
gap: 0 1.25rem;
max-width: 40rem;
}
.photo {
height: 175px;
}
}
@media screen and (min-width: 1200px) {
.section-center {
width: 95vw;
grid-template-columns: 1fr 1fr;
}
.photo {
height: 150px;
}
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<!-- end snippet -->
[enter image description here][1]
[1]: https://i.stack.imgur.com/HLvWY.png
**package.json**
{
"name": "reminder",
"version": "0.1.0",
"homepage": "https://github.com/khushi0909/Menu--Basic-Project-with-React",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"eslint": "^5.6.0",
"eslint-config-react": "^1.1.7",
"eslint-config-react-app": "^7.0.1",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-normalize": "^10.0.1",
"postcss-preset-env": "^7.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "^5.0.1"
},
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
"start": "react-scripts start",
"build": "set CI=false && react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"gh-pages": "^4.0.0",
"netlify-cli": "^2.37.0"
}
}
****index .htm****
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/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="%PUBLIC_URL%/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="%PUBLIC_URL%/manifest.json" />
<!--
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>Menu Complete</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`.
-->
</body>
</html>
screenshot of network
2
Answers
This is because you are passing relative path to the image in here:
Instead, what you should do is pass a path that would work in your browser (so the location should be written in relative to your
public
directory, not yourMyComponent.jsx
file). This is because you are not importing the images into your component, but you are loading them in the browser.Assuming your project structure is as follows:
All your
img
sources should have their dots removed:This way, when you open your website in the browser, images will get loaded properly.
I had a similar case, and it turned out that
react-router-dom
and the naming scheme in the/public
dir had a clash.My
react-router-dom
config was listening to:The component where I was expecting the image has this:
And my
/public
had the same name for the subdir:So what happened was that on first load of
http://localhost:3000/releases
it worked okay, but every subsequent load would show me the same status on the images like OP.What it was actually doing was trying load the image from
http://localhost:3000/releases/releases/ABC123.jpg
where it of course didn’t exist.The fix is to change the naming of either your route, or the subdir in public. I chose the latter, and with that change everything works smoothly:
In the project file structure:
And in the component:
changed to match the new subdir:
Update:
This version worked even in subpaths, like
<Route path='/releases/:id' ...