首页 > 解决方案 > 尝试映射一组 url 图像以使用 map 渲染到卡片

问题描述

正如标题所说,我正在尝试映射一组对象以获取要在卡片中呈现的照片网址。这些卡片仅在您填写审核表时才会出现。我尝试了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>☆&lt;/span><span>☆&lt;/span><span>☆&lt;/span><span>☆&lt;/span><span>☆&lt;/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>

          }


        }
      }
    }
    ```


标签: javascriptarraysreactjsjsxreact-hooks

解决方案


您需要从退货声明中取出照片并正确格式化地图

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>☆&lt;/span><span>☆&lt;/span><span>☆&lt;/span><span>☆&lt;/span><span>☆&lt;/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;```

推荐阅读