Возникли проблемы при переборе списка и печати элементов в React.

Код React:

import React from 'react';
import ReactDOM from 'react-dom';

class NewComponent extends React.Component {
    constructor(props){
        super(props);
        this.state = {myData: []}
    }

    componentWillMount(){
        let data = document.getElementById('demo').innerHTML;
        data = JSON.parse(data);
        this.setState({myData: data});
    }

    render() {
        return this.state.myData.map((item) => {
        return (
            <div>
                <h3>{item.title}</h3>
                <p>{item.description}</p>
            </div>
            );
         });
       }
     }


ReactDOM.render(
    <NewComponent />,
    document.getElementById('demo')
 )

И я получаю сообщение об ошибке:

bundle.js:830 Uncaught Error: NewComponent.render(): A valid React element 
(or null) must be returned. You may have returned undefined, an array or 
some other invalid object.

Я почти уверен, что есть некоторая проблема с возвратами в функции рендеринга Не уверен, в чем проблема.

РЕДАКТИРОВАТЬ

Я сделал следующие правки, ошибки больше нет, но ничего не отображается.

renderList() {
console.log("Running");
return  this.state.myData.map((item) => {
    <div>
      <h3>{item.title}</h3>
      <p>{item.description}</p>
    </div>
  });
}

render() {
    console.log(this.state.myData);
    if(this.state.myData.length)
        return <div>{this.renderList()}</div>
    else
        return <div>Loading...</div>
 }

В консоли Chrome я получаю:

(2) [{…}, {…}]
 0:{_id: {…}, description: "hello", title: "sankit"}
 1:{_id: {…}, description: "lets add some thing new", title: "hi"}
 length:2
 _proto_:Array(0)

 Running
0
Sankit Acharya 27 Авг 2017 в 22:41

4 ответа

Лучший ответ

Что вы можете сделать, это извлечь свой js-код из метода рендеринга в отдельный метод, например, так:

renderList() {
   return this.state.myData.map((item) => {
      <div>
       <h3>{item.title}</h3>
       <p>{item.description}</p>
      </div>
   })
}

Тогда в вашем методе рендеринга:

render() {
  if(this.state.myData.length){
    return (
       <div>{this.renderList()}</div>
    );
  }
  else
  {
    return (
      <div>Loading...</div>
    );
  }
}
1
Prakash Sharma 27 Авг 2017 в 20:28

Я думаю, что вы пропускаете возврат в renderList -> .map

Это должно сработать.

renderList() {
    return this.state.myData.map((item) => {
        return (      
            <div>
            <h3>{item.title}</h3>
            <p>{item.description}</p>
            </div>
        );
    });
}

render() {
    if(this.state.myData.length){
        return (
            <div>{this.renderList()}</div>
        );
    }
    else {
        return (
            <div>Loading...</div>
        );
    }
}
0
user1891758 11 Окт 2018 в 09:03

Измените это следующим образом: при использовании map следует использовать атрибут key для индекса

makeUI() {
        if(!this.state.myData.length)
            return

        return this.state.myData.map((item, index) => {
        return (
            <div key={index}>
                <h3>{item.title}</h3>
                <p>{item.description}</p>
            </div>
            )
         })
    }

    render() {
        return (<div>
            { this.makeUI() }
            </div>
        )
    }
0
Kalaikumar Thangasamy 27 Авг 2017 в 21:12

Вы можете обернуть его корневым элементом, например div, Функции рендеринга версии 15 поддерживают возврат только одного элемента.

 render() {
    <div>{this.state.myData.map((item) =>
        <div>
            <h3>{item.title}</h3>
            <p>{item.description}</p>
        </div>
          )}</div>
   }
 }
0
felixmosh 27 Авг 2017 в 19:58