2017-04-22 87 views
1

ERROR:如何在React中以编程方式呈现表格?

main.js:1583未被捕获的错误:对象是不作为阵营子有效(实测值:[对象HTMLTableElement])。如果您打算渲染一组儿童,请改用数组,或者使用React附加组件中的createFragment(object)来包装对象。


CODE:

var size = 40 

var Board = createReactClass ({ 

    getInitialState() { 
     var array = []; 
     var cellsArray = []; 
     for (var i = 0; i < size; i ++) { 
      array.push(cellsArray); 
      for (var j = 0; j > size; j++) { 
       array[i].push(<Cell start={this.props.start}/>); 
      } 
     } 

     return { 
      array: array 
     }; 

    }, 

    render() { 

    var i = 0; 

    var tableData = this.state.array.map(rowData => { 
     i++ 
     return (
      <tr key={i}> 
       { 
        rowData.map(cellData => { 
         return ({cellData}); 
        }) 
       } 
      </tr> 
     ); 
    }) 

    return (
     <table> 
      <tbody> 
       {tableData} 
      </tbody> 
     </table> 
    ); 

} 

}) 

var Cell = createReactClass ({ 

    getInitialState() { 
     return { 
      selected : false, 
     } 
    }, 

    handleClick() { 
     this.setState({ 
      selected: !this.state.selected 
     }) 
    }, 

    render() { 
     return <td onClick = {this.handleClick} className={this.state.selected ? "cell selected" : "cell"}></td>; 
    } 
}) 

问题:

我想使编程方式创建表。我怎样才能做到这一点 ?


UPDATE:

enter image description here

enter image description here


CSS:

.cell { 
    width: 1em; 
    height: 1em; 
    border: 1px solid #ddd; 
} 

.selected { 
    background-color: black; 
} 

table { 
    border: 1px solid black; 
    border-collapse: collapse; 
    margin: auto; 
    margin-bottom: 50px; 
} 
+0

'使用document.createElement( '表')'是一个坏主意,只是返回'

{tableData.map(rowData => ...'等等 – elmeister

+0

@ elmeister请把这个答案放在答案中,以便我可以接受它 – Coder1000

回答

3

您需要创建它React的方式。您的createTable方法应该如下所示。

createTable(tableData) { 
return (
    <table> 
    <tbody> 
    { 
    tableData.map(rowData => { 
     return (<tr key={rowData.Id}> 
      { 
      rowData.map(cellData => { 
       return (<td key={cellData}> {cellData} </td>); 
      }) 
      } 
     </tr>); 
    }) 
    } 
    </tbody> 
    </table> 
) 

注意:您需要在'maps'中放入一个唯一的jsx根键。确定每次迭代的唯一键。作为最后的手段,您可以使用index,但不建议这样做。

编辑:更新了新的变化

在你更新的代码,该td是空的,因此其在页面上显示为空。

其他的变化,你将需要

你的初始状态应该不会产生JSX。它只能用于计算初始状态并返回一个普通对象。您正在返回一个包含其中的JSX元素数组的对象,这基本上违反了React的目的,它需要根据prop/state更改适当地动态更新DOM。您的initialState应该只包含构建所需DOM元素所需的数据。

getInitialState() { 
    var array = []; 
    var cellsArray = []; 
    for (var i = 0; i < size; i ++) { 
     array.push(cellsArray); 
     for (var j = 0; j > size; j++) { 
      array[i].push(/* push data that you need to construct your cell */); 
     } 
    } 

    return { 
     array: array 
    }; 

} 

然后在您的tableData函数中,您需要构造所需的JSX。这个函数在render里面被调用,这是产生DOM元素的完美地方。

var tableData = this.state.array.map(rowData => { 
    i++ 
    return (
     <tr key={i}> 
      { 
       rowData.map(cellData => { 
        return <Cell key={cellData} data={cellData} start={this.props.start} /> 
       }) 
      } 
     </tr> 
    ); 
}) 

最后,在你的Cellrender方法,你需要通过一些孩子td为它是在屏幕上可见。在你的问题中它是空的,所以你发布的图像显示了DOM元素,它是空的是正确的行为。你需要做类似下面

render() { 
    return (<td onClick = {this.handleClick} className={this.state.selected ? "cell selected" : "cell"}> 
{this.props.data } 
{ /* or whatever data you want to be put here */ } 
    </td>); 
} 
+0

警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具,使用

。 – Coder1000

+0

检查顶级渲染调用。现在要更新了,总是需要修改代码以适合你的需求 – Panther

+0

直到实际工作之前我才接受它 – Coder1000

相关问题