简体   繁体   中英

How to render an array of object in ReactJS?

I'm new to ReactJS and am attempting to render an individual object that contains an array of objects.

But I can't get around the Uncaught TypeError: this.props.data.map is not a function error.

How do I get at the assets array within the parent object (ie data)?

Here's my JS currently:

<script type="text/babel">
var ProjectContainer = React.createClass({
    loadProjectsFromServer: function() {
    $.ajax({
        url: this.props.url,
        dataType: 'json',
        cache: false,
        success: function(data) {
            console.log(data)
            this.setState({data: data});
        }.bind(this),
        error: function(xhr, status, err) {
            console.error(this.props.url, status, err.toString());
        }.bind(this)
        });
    },
    getInitialState: function () {
        return {data: []};
    },
    componentDidMount: function() {
        this.loadProjectsFromServer();
        setInterval(this.loadProjectsFromServer, this.props.pollInterval);
    },
    render: function () {
        return (
            <Project data={ this.state.data } />
        );
    }
});
var Project = React.createClass({
    rawMarkup: function() {
        var rawMarkup = this.props.data.description_html;
        return { __html: rawMarkup };
    },
    render: function() {
        var assetNodes = this.props.data.map(function (asset) {
            return (
                <Asset key={ asset.pk } art={ asset.art } project={ asset.project } description={ asset.description } />
            );
        });
        return (
            <div>
                { this.props.data.assets }
                <header>
                    <h2 className="lead_head">{ this.props.data.client_name }</h2>
                </header>
                <span dangerouslySetInnerHTML={ this.rawMarkup() } />
                <ul className="project_asset_list">
                    { assetNodes }
                </ul>
            </div>
        );
    }
});
var Asset = React.createClass({
    render: function() {
        return (
            <li className="asset">
                <span className="asset_description">{ this.props.project }{ this.props.description }</span>
                <a href={ this.props.art } data-title={ this.props.project } data-lightbox="roadtrip">
                    <img src={ this.props.art } alt={ this.props.description } />
                </a>
            </li>
        )
    }
});
ReactDOM.render(
    <ProjectContainer url="{% url 'portfolio_project_detail_api' slug=slug %}" pollInterval={2000} />,
    document.getElementById('project_indiv')
);
</script>

Here's the JSON I'm working with:

{
    "pk": 2,
    "client_name": "Paz Studios",
    "slug": "paz-studios",
    "description": "[Paz Studios](https://www.facebook.com/pazstudios) offers yoga and Pilates for students at all levels. (I'm a devoted beginner, and their instructors do a great job of making me feel like I belong, alongside all the other limber wonders.)\r\n\r\nI worked with them as they prepared for their grand opening in November 2013 to craft a logo that found an intersection of simplicity and nature.\r\n\r\nI've continued working with them to create posters, flyers, and other promotional materials. And they've continued to work with me: I've got their advanced classes on my bucket list.",
    "description_html": "<p><a href=\"https://www.facebook.com/pazstudios\">Paz Studios</a> offers yoga and Pilates for students at all levels. (I&#8217;m a devoted beginner, and their instructors do a great job of making me feel like I belong, alongside all the other limber&nbsp;wonders.)</p>\n<p>I worked with them as they prepared for their grand opening in November 2013 to craft a logo that found an intersection of simplicity and&nbsp;nature.</p>\n<p>I&#8217;ve continued working with them to create posters, flyers, and other promotional materials. And they&#8217;ve continued to work with me: I&#8217;ve got their advanced classes on my bucket&nbsp;list.</p>",
    "lead_art": "http://127.0.0.1:8000/media/images/portfolio/projects/portfolio-preview-paz.png",
    "completion_date": "2013-11-01",
    "project_detail": {
        "self": "http://127.0.0.1:8000/work/paz-studios/?format=json"
    },
    "assets": [
        {
            "pk": 3,
            "description": "logo",
            "project": "Paz Studios",
            "art": "http://127.0.0.1:8000/media/images/portfolio/assets/portfolio-asset-paz-logo.png"
        },
        {
            "pk": 4,
            "description": "schedule poster (11x17)",
            "project": "Paz Studios",
            "art": "http://127.0.0.1:8000/media/images/portfolio/assets/paz-march-flyer_2.png"
        },
        {
            "pk": 5,
            "description": "class flyer (8.5x11)",
            "project": "Paz Studios",
            "art": "http://127.0.0.1:8000/media/images/portfolio/assets/paz-vinyasa-class_2.png"
        }
    ]
}

First in your Ajax all you have write the line in success function this.setState({data: data}); it's not going to work, your loadProjectsFromServer function should be look like

 loadProjectsFromServer: function() {
  var Current=this;
$.ajax({
    url: this.props.url,
    dataType: 'json',
    cache: false,
    success: function(data) {
        console.log(data)
        Current.setState({data: data});
    }.bind(this),
    error: function(xhr, status, err) {
        console.error(this.props.url, status, err.toString());
    }.bind(this)
    });
},

when you will write keyword this and the scope of this keyword is your ajax call and that function don't have a state so you have to store your component in variable and then use that variable to access the state in your ajax call

Second if you find the data in your component then your data should in form of JSON if your data in form of object then you have to write like

 var actualdata=JSON.parse(this.props.data);
 var assetNodes = Object.keys(actualdata).map(function (asset) {
        return (
            <Asset key={ actualdata[asset].pk } art={ actualdata[asset].art } project={ actualdata[asset].project } description={ actualdata[asset].description } />
        );
    });

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