通过迭代生成组件

时间:2016-06-21 01:47:18

标签: javascript reactjs ecmascript-6

有些奇怪的事情发生了:
这是我的初始状态(.js文件)

import moment       from 'moment';

let date = moment();
var previousDate = moment("2015-12-25");

export const projects = [
      {
        "id": 0,
        "metadata": {
          "fields": 
            [{
              "id":     1,
              "order":  1,
              "name":   "Name",
              "value":  "Collection 1"
            },
            {
              "id":     2,
              "order":  2,
              "name":   "Created On", 
              "value":  date
            },
            {
              "id":     3,
              "order":  3,
              "name":   "Last Modified On", 
              "value":  previousDate
            },
            {
              "id":     4,
              "order":  4,
              "name":   "Status", 
              "value":  "Filed"
            }],

          "tags": 
            [{
              "id":     1,
              "order":  1,
              "value":  "tag1"
            },
            {
              "id":     2,
              "order":  2,
              "value":  "tag2"
            },
            {
              "id":     3,
              "order":  3,
              "value":  "tag3"
            },
            {
              "id":     4,
              "order":  4,
              "value":  "tag4"
            }]   
        }
      }

这是ProjectsList.js

import React          from 'react';
import Project        from './Project';
import { projects }   from 'initialState';

export default (props) => {
  return(
    <div className="projectsList">
      {projects.map(project => (
        <article key={project.id}><Project fields={project.metadata.fields} /></article>
      ))}
    </div>
  )
}

这是Project.js

import React  from 'react';

export default (props) => {
  return(
    <ul className="fields">
      {props.fields.map(field => <li key={field.id}>{field.name}</li>) }
    </ul>
  )
}

我试图在列表中呈现一堆项目,每个项目都包含一堆显示的元数据键值对。

所以基本上,接线无关紧要,一切正常 除此之外:

如果你查看初始状态文件(那里的第一个),fields中有一个包含多个对象的数组。每个对象显示4个键值对

  • id
  • 顺序
  • 名称

现在,在Project.js,我去的地方

{props.fields.map(field => <li key={field.id}>{field.name}</li>) }

看起来我可以切换{field.name} {field.id},以便在文本中显示ID。或者我可以{field.order}来显示订单。

但奇怪的是,如果我想显示字段的实际值,就像{field.value}一样,它会抛出。

invariant.js?4599:38

Uncaught Invariant Violation: Objects are not valid as a React child (found: Mon Jun 20 2016 21:40:33 GMT-0400). 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 `StatelessComponent`.   

我甚至将每个value中的字符串fields更改为val,以确保value不是某种类型。一个保留字。

还是扔了。

任何人都可以帮我理解我做错了什么,这里? 谢谢你们。

2 个答案:

答案 0 :(得分:2)

您正在为状态文件中的value属性分配变量值,这些属性很可能不是字符串,而是对象:

export const projects = [{
    "id": 0,
    "metadata": {
      "fields": 
        [
        ...
        {
          "id":     2,
          "order":  2,
          "name":   "Created On", 
          "value":  date                 // one
        },
        {
          "id":     3,
          "order":  3,
          "name":   "Last Modified On", 
          "value":  previousDate         // and another one
        },
        ...
        ]
    ...    
    }
}

答案 1 :(得分:1)

如果typeof children返回"object"(并且children既不是数组,也不是ReactElement),它会抛出: https://github.com/facebook/react/blob/dc6fc8cc0726458a14f0544a30514af208d0098b/src/shared/utils/traverseAllChildren.js#L169

这是展示这一点的最简单的例子:

const IllegalComponent = () => <span>{{}}</span>

您应该提供一个字符串(或数字),以便React可以将其作为<li>中的子项内联。儿童应该是可渲染的东西并实施ReactNode

如果孩子是一个对象,React将不知道如何渲染它。您应该显式将值转换为String。

试试看它是否有效:

{props.fields.map(field => <li key={field.id}>{field.value.toString()}</li>) }