嗨,我无法看到图像,我已经呈现在菜单组件如下,并attached截图,可以sommeone看到什么问题,我的图像文件夹是在公共文件夹,嗨,我无法看到图像,我已经呈现在菜单组件如下,并附上截图,可以sommeone看到什么问题,我的图像文件夹是在公共文件夹
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>
2条答案
按热度按时间pieyvz9o1#
这是因为您在这里传递的是图像的相对路径:
相反,你应该做的是传递一个在你的浏览器中工作的路径(所以位置应该相对于你的
public
目录而不是你的MyComponent.jsx
文件写入)。这是因为你没有将图像导入到你的组件中,而是在浏览器中加载它们。假设您的项目结构如下:
所有
img
源都应该删除它们的点:这样,当您在浏览器中打开网站时,图像将正确加载。
gab6jxml2#
我有一个类似的案例,结果发现
react-router-dom
和/public
目录中的命名方案有冲突。我的
react-router-dom
配置正在收听:我期望映像所在的组件具有以下内容:
我的
/public
有相同的子目录名称:所以发生的事情是,在第一次加载
http://localhost:3000/releases
时,它工作正常,但随后的每次加载都会在图像上显示相同的状态,如OP。它实际上是试图从
http://localhost:3000/releases/releases/ABC123.jpg
加载图像,当然它不存在。修复方法是更改路由的命名,或者公开的子目录。我选择了后者,这样一切都很顺利:
在项目文件结构中:
在组件中:
更改以匹配新的子目录:
更新:这个版本甚至可以在子路径中工作,比如
<Route path='/releases/:id' ...