如何在ReactJS中呈现对象数组?

时间:2015-11-09 02:17:30

标签: javascript reactjs

我是ReactJS的新手,我正在尝试渲染一个包含对象数组的单个对象。

但我无法解决Uncaught TypeError: this.props.data.map is not a function错误。

如何获取父对象(即数据)中的assets数组?

这是我目前的JS:

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

这是我正在使用的JSON:

{
    "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"
        }
    ]
}

1 个答案:

答案 0 :(得分:0)

首先在你的Ajax中你已经写下了成功函数this.setState({data: data}); 它不能正常工作,你的 loadProjectsFromServer 函数应该看起来像

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

当您编写关键字this时,此关键字的范围是您的ajax调用,并且该函数没有状态,因此您必须将组件存储在变量中,然后使用该变量访问你的ajax电话中的状态

其次,如果您在组件中找到数据,那么如果您的数据采用对象形式,那么您的数据应采用JSON格式,那么您必须编写

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