简体   繁体   中英

How to access nested arrays in JSX

I am new react-redux applications. I am trying to make a wine list that will display a ranking (x out of 5 stars) based on the average number of stars in a json file from the server (wines.json). In my Wines.jsx file, I render a few of the json categories from wines such as {wine.name} and {wine.vintage} , but when I try and render {wine.ratings} I get this error to the console:

Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {stars}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {stars}). If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of Wines .

It seems as though since in the wines.json file 'ratings' contains a nested array composed of 'star' objects, {wine.ratings} wont render. What must I do to gain access to that data?

wines.json:

"wines": [{
"id": "f2ca57a5-d9da-4808-9164-8d6e0da0aef5",
"name": "Apothic Red",
"vintage": "2015",
"vineyard": "Apothic",
"type": "Red Blend",
"region": "California",
"unitsSold": 51,
"ratings": [{
  "stars": 5
}, {
  "stars": 3
}]
  }...

wines.jsx:

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

import * as actionCreators from './wineActions';

import './wines.scss';
import { SplitButton } from 'react-bootstrap';
import './ratings';


export class Wines extends Component {
  componentDidMount() {
    this.props.actions.fetchWines();
  }

  render() {
    return (
      <div className="wines">
        <row>
          <h1 className="wines__title" >Wine List</h1>
        </row>
        <row>
          <SplitButton title="Select Year"></SplitButton>
        </row>  
        <ul className="wines__list">
          {
            this.props.wines
              .map(wine => 
                <div key={wine.id}>

                      <div className='divLeft'>
                        <img src='front-end-challenge--provo17/client/wines/wine-placeholder.png' />
                      </div>

                      <div className='divRight'>
                        <h3>{wine.name}, {wine.vintage}</h3>
                        <br />
                        <p>{wine.type}</p>
                        <span>{wine.ratings}</span>
                        <p>({wine.unitsSold})</p>
                      </div>

                      <hr />

                </div>)
          }
        </ul>
      </div>
    );
  }
}



// React.render(<FormComponent />, document.getElementById('star-rating'));

Wines.propTypes = {
  wines: PropTypes.array,
  actions: PropTypes.object
};

function mapStateToProps(state) {
  return {
    ...state.wines
  };
}

function mapDispatchToProps(dispatch) {
  return { actions: bindActionCreators(actionCreators, dispatch) };
}

    export default connect(mapStateToProps, mapDispatchToProps)(Wines);

wineActions.js:

export function receiveWines(wines) {
  return {
    type: 'FETCH_WINES_SUCCESS',
    wines
  };
}

export function fetchWines() {
  return function(dispatch) {

    return fetch(`https://sb-challenge-provo17.c9users.io/api/v1/wines`)
      .then(response => {
        var resp = response.json(); 
        return resp;
      })

      .then(json => {
        dispatch(receiveWines(json.wines)
      );
      });
  };
}

ratings is an array of objects, and objects are not valid react children as the error message suggests. You can map over ratings array just like you are mapping through the wines array. You also need to provide keys. Usually you would use ids for those, but your ratings don't have ids. Although not as good, you can use array indices as keys.

So instead of <span>wine.ratings</span> have <span>{wine.ratings.map((rating,indx) => <span key={indx}>{rating.stars}</span>)}</span>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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