Как получить доступ к вложенным массивам в JSX

Я новые реактивно-редукционные приложения. Я пытаюсь составить карту вин, в которой будет отображаться рейтинг (x из 5 звезд) на основе среднего количества звезд в файле json с сервера (wines.json). В моем файле Wines.jsx я отображаю несколько категорий json из таких вин, как {wine.name} а также {wine.vintage}, но когда я пытаюсь сделать {wine.ratings} Я получаю эту ошибку в консоли:

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.json "рейтинги" содержат вложенный массив, состоящий из "звездных" объектов, {wine.ratings} не будет оказывать. Что я должен сделать, чтобы получить доступ к этим данным?

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)
      );
      });
  };
}

1 ответ

ratings является массивом объектов, и недопустимые объекты реагируют на дочерние элементы, как предполагает сообщение об ошибке. Вы можете отобразить массив оценок так же, как вы отображаете массив wines. Вам также необходимо предоставить ключи. Обычно вы используете идентификаторы для них, но ваши рейтинги не имеют идентификаторов. Хотя это не так хорошо, вы можете использовать индексы массивов в качестве ключей.

Так что вместо <span>wine.ratings</span> иметь <span>{wine.ratings.map((rating,indx) => <span key={indx}>{rating.stars}</span>)}</span>

Другие вопросы по тегам