简体   繁体   English

尝试映射到一系列网址图片上,以使用地图渲染到卡片上

[英]Try to map over an array of url images to render to cards using map

As the title says I am trying to map over an array of objects to get the photo urls to render in the cards. 就像标题所说的那样,我试图映射到一系列对象上,以使照片URL呈现在卡片中。 The cards only populate when you fill out a review form. 仅当您填写评论表格时,卡片才会填充。 I tried faker js but it would render a blank image so I thought that an array of objects would do the trick but I keep getting the error "Objects are not valid as a React child (found: object with keys {id, img}). If you meant to render a collection of children, use an array instead." 我尝试使用伪造的js,但是它会呈现空白图像,因此我认为可以使用对象数组来解决问题,但是我不断收到错误消息:“对象作为React子对象无效(找到:具有键{id,img}的对象)如果要渲染子级集合,请改用数组。” Not really sure I know what I am doing wrong. 不确定我知道我在做什么错。 Please assistance would be appreciated. 请协助,将不胜感激。

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>

          }


        }
      }
    }
    ```


you need to take Photo out of return statement and format map properly 您需要从退货声明中取出照片并正确格式化格式

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;```

Your problem is this, 你的问题是

const Photo = ({postsdata}) => (
  <div>
     {postsdata.map(postdata => (
       <Image className='photoOfOrder' key={postdata.img} src={postdata.img} wrapped ui={false} />
     ))}
  </div>
)

We never write functions inside of return, you just need to do this, 我们从不在return内部编写函数,您只需要这样做,

<div>
     {postsdata.map(postdata => (
       <Image className='photoOfOrder' key={postdata.id} src={postdata.img} wrapped ui={false} />
     ))}
</div>

Note: You have provided key={postdata.img} , when you have id then you should provide id as key which is more useful. 注意:您已经提供了key={postdata.img} ,当您拥有id您应该提供id作为key ,这会更有用。


Update 更新资料

To match any image randomly you can do this, 要随机匹配任何图像,您可以执行此操作,

{postsdata.filter(postdata => postdata.id === props.index).map(data=> <Image className='photoOfOrder' key={data.id} src={data.img} wrapped ui={false} />)}

You need to pass index from parent component as, 您需要通过父组件传递index

<UserCard className='onecard' tileData={oneRest} setReviews={this.props.setReviews} index={Math.floor(Math.random()*15)+1} />

Here Math.floor(Math.random()*15)+1 will give you random number between 1 to 15. 这里Math.floor(Math.random()*15)+1将为您提供1到15之间的随机数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM