尝试使用 map 将 url 图像数组映射到卡片上
2019-08-03
2298
正如标题所述,我正在尝试映射对象数组以获取要在卡片中呈现的照片网址。只有当您填写评论表格时,卡片才会填充。我尝试了 faker js,但它会呈现空白图像,所以我认为对象数组可以解决问题,但我一直收到错误“对象作为 React 子项无效(找到:带有键 {id, img} 的对象)。如果您想要呈现子项集合,请改用数组。”我不太确定我做错了什么。请提供帮助,不胜感激。
import { Card, Image } from 'semantic-ui-react'
import { Link } from 'react-router-dom';
import { axiosWithAuth } from '../utils/auth'
import "./userInfo.css"
function UserCard(props) {
// console.log("cardprops", props)
const { setReviews } = props;
// const deleteReview = data => {
// console.log(data.id);
// setReviews(reviews => [...reviews.filter(review => review.id !== data.id)]);
// };
const deleteReview = restaurant => {
axiosWithAuth().delete(`https://foodiefun-api.herokuapp.com/api/reviews/${restaurant.id}`, restaurant)
.then(res => {
setReviews(reviews => [...reviews.filter(review => review.id !== restaurant.id)]);
})
.catch(err => {
console.log('can not delete message', err)
})
}
let postsdata = [
{
"id": 1,
"img": "https://www.thegrilledcheesetruck.com/wp-content/uploads/2017/03/gct-menu21-800x600.jpg"
},
{
"id": 2,
"img": "https://blueprint-api-production.s3.amazonaws.com/uploads/card/image/917437/3261d336-f53b-44a0-abdb-69792f60af66.jpg"
},
{
"id": 3,
"img": "https://tastychomps.com/wp-content/uploads/2019/06/P6150451-800x600.jpg"
},
{
"id": 4,
"img": "https://cdn.styleblueprint.com/wp-content/uploads/2019/07/SB-BHM-Food-Truck-Mustard-Seed-Food-Co-hot-mess-fries.jpg"
},
{
"id": 5,
"img": "https://snworksceo.imgix.net/cav/8ed1b226-a90d-4c2d-9216-99689efa4334.sized-1000x1000.jpg?w=800"
},
{
"id": 6,
"img": "https://www.whatsonnetwork.co.uk/uploads/800x600/e6e34f13ec62f43638b808feb55fab9e.jpg"
},
{
"id": 7,
"img": "https://news.wbfo.org/sites/wbfo/files/styles/medium/public/201907/table_food.jpg"
},
{
"id": 8,
"img": "https://craftcleaver.co.uk/wp-content/uploads/2017/10/sharing-platter-on-blue-square-angle-800x600.jpg"
},
{
"id": 9,
"img": "https://theculturetrip.com/wp-content/uploads/2015/12/800px-Hoppers_at_house_of_dosas.jpg"
},
{
"id": 10,
"img": "https://s3-prod.adage.com/s3fs-public/styles/800x600/public/80_ChickenMcNuggetHappyMeal.jpg"
},
{
"id": 11,
"img": "https://porteliotfestival.com/wp-content/uploads/2017/04/Port-Eliot-Festival-2017-294A3665-800x600.jpg"
},
{
"id": 12,
"img": "https://www.mykadhai.com/assets/images/img-4142-2000x1500-800x600.jpg"
},
{
"id": 13,
"img": "https://nwatravelguide.com/wp-content/uploads/2018/05/The-Hive-800x600.jpg"
},
{
"id": 14,
"img": "https://www.mjseatery.com/images/buritto.jpg"
},
{
"id": 15,
"img": "https://imagevars.gulfnews.com/2019/07/18/Deccan-Delight-biryani_16c043a76bd_original-ratio.jpg"
}
]
return (
<Card>
<div className="rating">
<span>☆</span><span>☆</span><span>☆</span><span>☆</span><span>☆</span>
</div>
const Photo = ({postsdata}) => (
<div>
{postsdata.map(postdata => (
<Image className='photoOfOrder' key={postdata.img} src={postdata.img} wrapped ui={false} />
))}
</div>
)
<Card.Content>
<Card.Header
className='restaurantName'>{props.tileData.restaurantName}
</Card.Header>
<Card.Meta>
<span className='dateOfVisit'><b>Date Visited: </b> {props.tileData.dateOfVisit}</span>
</Card.Meta>
<Card.Meta>
<span className='restaurantType'><b>Type of Food: </b>{props.tileData.restaurantType}</span>
</Card.Meta>
<Card.Meta>
<span className='waitTime'><b>Wait Time: </b>{props.tileData.waitTime} minutes</span>
</Card.Meta>
<Card.Meta>
<span className='menuItem'><b>Item Ordered: </b>{props.tileData.menuItem}</span>
</Card.Meta>
<Card.Meta>
<span className='price'><b>Price: $</b>{props.tileData.price}</span>
</Card.Meta>
<Card.Meta>
<span className='foodRating'><b>Food rating: </b>{props.tileData.foodRating} Stars</span>
</Card.Meta>
<Card.Meta>
<span className='comments'><b>Comments: </b>{props.tileData.comments}</span>
</Card.Meta>
</Card.Content>
<Link to={`/edit/${props.tileData.id}`}>
<button className='edit-btn btn btn-bubble'>
Edit
</button></Link>
<button className='delete-btn btn2 btn-bubble2'
onClick={() => deleteReview(props.tileData)}>
Delete
</button>
</Card >
)
}
export default UserCard;```
UderInfo.js
The only other file for the cards
```import React, { Component } from 'react';
import UserCard from './userCard';
import SearchSelect from './SearchSelect'
import "./userInfo.css";
export default class userInfo extends Component {
constructor(props) {
super(props);
this.state = { selectedFilterThingies: [] }
this.searchSelectHandler = this.searchSelectHandler.bind(this);
}
searchSelectHandler(value) {
this.setState({ selectedFilterThingies: value });
console.log("searched array", value)
}
// ["Fast Food", "Japanese", "Mexican" ]
render() {
//console.log("updatehandler", {this.searchSelectHandler})
if (!this.props.data) {
return <div>Loading Foodie Cards...</div>
}
else {
if (this.state.selectedFilterThingies.length < 1) {
return <section className='userCard '>
<div>
<div>
<SearchSelect updateHandler={this.searchSelectHandler} data={this.props.data} />
</div>
<div className='gridview' >
{this.props.data.map(oneRest => (
<UserCard className='onecard' tileData={oneRest} setReviews={this.props.setReviews} />
))}
</div>
</div>
</section>
}
else {
let newarray = []
//check for restuarant type and render from newarray
newarray = (this.props.data.filter(item =>
this.state.selectedFilterThingies.some(filter => filter === item.restaurantType)))
console.log("newarray", newarray)
return <section className='userCard '>
<div>
<div>
<SearchSelect updateHandler={this.searchSelectHandler} data={this.props.data} />
</div>
<div className='gridview'>
{newarray.map(oneRest => (
<UserCard className='onecard' tileData={oneRest} setReviews={this.props.setReviews} />
))}
</div>
</div>
</section>
}
}
}
}
```
2个回答
您需要将照片从返回语句中取出并正确格式化地图
import { Card, Image } from 'semantic-ui-react'
import { Link } from 'react-router-dom';
import { axiosWithAuth } from '../utils/auth'
import "./userInfo.css"
function UserCard(props) {
// console.log("cardprops", props)
const { setReviews } = props;
// const deleteReview = data => {
// console.log(data.id);
// setReviews(reviews => [...reviews.filter(review => review.id !== data.id)]);
// };
const deleteReview = restaurant => {
axiosWithAuth().delete(`https://foodiefun-api.herokuapp.com/api/reviews/${restaurant.id}`, restaurant)
.then(res => {
setReviews(reviews => [...reviews.filter(review => review.id !== restaurant.id)]);
})
.catch(err => {
console.log('can not delete message', err)
})
}
let postsdata = [
{
"id": 1,
"img": "https://www.thegrilledcheesetruck.com/wp-content/uploads/2017/03/gct-menu21-800x600.jpg"
},
{
"id": 2,
"img": "https://blueprint-api-production.s3.amazonaws.com/uploads/card/image/917437/3261d336-f53b-44a0-abdb-69792f60af66.jpg"
},
{
"id": 3,
"img": "https://tastychomps.com/wp-content/uploads/2019/06/P6150451-800x600.jpg"
},
{
"id": 4,
"img": "https://cdn.styleblueprint.com/wp-content/uploads/2019/07/SB-BHM-Food-Truck-Mustard-Seed-Food-Co-hot-mess-fries.jpg"
},
{
"id": 5,
"img": "https://snworksceo.imgix.net/cav/8ed1b226-a90d-4c2d-9216-99689efa4334.sized-1000x1000.jpg?w=800"
},
{
"id": 6,
"img": "https://www.whatsonnetwork.co.uk/uploads/800x600/e6e34f13ec62f43638b808feb55fab9e.jpg"
},
{
"id": 7,
"img": "https://news.wbfo.org/sites/wbfo/files/styles/medium/public/201907/table_food.jpg"
},
{
"id": 8,
"img": "https://craftcleaver.co.uk/wp-content/uploads/2017/10/sharing-platter-on-blue-square-angle-800x600.jpg"
},
{
"id": 9,
"img": "https://theculturetrip.com/wp-content/uploads/2015/12/800px-Hoppers_at_house_of_dosas.jpg"
},
{
"id": 10,
"img": "https://s3-prod.adage.com/s3fs-public/styles/800x600/public/80_ChickenMcNuggetHappyMeal.jpg"
},
{
"id": 11,
"img": "https://porteliotfestival.com/wp-content/uploads/2017/04/Port-Eliot-Festival-2017-294A3665-800x600.jpg"
},
{
"id": 12,
"img": "https://www.mykadhai.com/assets/images/img-4142-2000x1500-800x600.jpg"
},
{
"id": 13,
"img": "https://nwatravelguide.com/wp-content/uploads/2018/05/The-Hive-800x600.jpg"
},
{
"id": 14,
"img": "https://www.mjseatery.com/images/buritto.jpg"
},
{
"id": 15,
"img": "https://imagevars.gulfnews.com/2019/07/18/Deccan-Delight-biryani_16c043a76bd_original-ratio.jpg"
}
]
const Photo = postsdata.map(postdata => (
<Image className='photoOfOrder' key={postdata.img} src={postdata.img} wrapped ui={false} />
);
return (
<Card>
<div className="rating">
<span>☆</span><span>☆</span><span>☆</span><span>☆</span><span>☆</span>
</div>
<div>
{Photo}
</div>
<Card.Content>
<Card.Header
className='restaurantName'>{props.tileData.restaurantName}
</Card.Header>
<Card.Meta>
<span className='dateOfVisit'><b>Date Visited: </b> {props.tileData.dateOfVisit}</span>
</Card.Meta>
<Card.Meta>
<span className='restaurantType'><b>Type of Food: </b>{props.tileData.restaurantType}</span>
</Card.Meta>
<Card.Meta>
<span className='waitTime'><b>Wait Time: </b>{props.tileData.waitTime} minutes</span>
</Card.Meta>
<Card.Meta>
<span className='menuItem'><b>Item Ordered: </b>{props.tileData.menuItem}</span>
</Card.Meta>
<Card.Meta>
<span className='price'><b>Price: $</b>{props.tileData.price}</span>
</Card.Meta>
<Card.Meta>
<span className='foodRating'><b>Food rating: </b>{props.tileData.foodRating} Stars</span>
</Card.Meta>
<Card.Meta>
<span className='comments'><b>Comments: </b>{props.tileData.comments}</span>
</Card.Meta>
</Card.Content>
<Link to={`/edit/${props.tileData.id}`}>
<button className='edit-btn btn btn-bubble'>
Edit
</button></Link>
<button className='delete-btn btn2 btn-bubble2'
onClick={() => deleteReview(props.tileData)}>
Delete
</button>
</Card >
)
}
export default UserCard;```
Mojahed Elbakre
2019-08-03
你的问题是这样的,
const Photo = ({postsdata}) => (
<div>
{postsdata.map(postdata => (
<Image className='photoOfOrder' key={postdata.img} src={postdata.img} wrapped ui={false} />
))}
</div>
)
我们从不在返回内部编写函数,你只需要这样做,
<div>
{postsdata.map(postdata => (
<Image className='photoOfOrder' key={postdata.id} src={postdata.img} wrapped ui={false} />
))}
</div>
注意:
你已经提供了
key={postdata.img
,当你有
id
时,你应该提供
id
作为
key
,这更有用。
更新
要随机匹配任何图像,您可以这样做,
{postsdata.filter(postdata => postdata.id === props.index).map(data=> <Image className='photoOfOrder' key={data.id} src={data.img} wrapped ui={false} />)}
您需要从父组件传递
index
,
<UserCard className='onecard' tileData={oneRest} setReviews={this.props.setReviews} index={Math.floor(Math.random()*15)+1} />
这里
Math.floor(Math.random()*15)+1
将为您提供 1 到 15 之间的随机数。
ravibagul91
2019-08-03