在react中渲染对象数组

时间:2018-11-01 14:37:55

标签: javascript html reactjs

我是新来的反应者,所以我不确定这里出了什么问题... 我正在尝试创建输入框的3x3结构。这就是我想出的

function Square(prop){
    return (<input type = 'text' class='w-25'  style="display:inline-block">${prop.key}</input>);
}

function Row(props){
    const row =[];
    for( let i=props.key*3;i<(props.key+3);i++){
        row.push(<Square key ={i}/>);
    }
    return (row);
}

class Box extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            squares: Array(9).fill(null),
            xIsNext: true,
        };
    }
    render(){
        let board =[];
        for( let i=0; i<3;i++){
            board.push(<div><Row key={i} /></div>);
        } 
        return (board);
    }
} 
ReactDOM.render(
    <Box />,
    document.getElementById('root')
  );

但是我得到了错误

  

警告:数组或迭代器中的每个子代均应具有唯一的“键”道具。

就我的Dom而言,三行已呈现为

  

  任何帮助将不胜感激

更新

在尝试了下面给出的一些答案之后,我最终只得到了一行4个输入框...尽管我在循环中只指定了3个。为什么有人可以解释一下,我又指定了2行。这是新代码

function Square(prop){
    return (<input type = 'text' id={prop.value} value={'x'}></input>);
}

function Row(props){
    const row =[];
    for( let i=props.value*3;i<(props.value+3);i++){
        const val = `${i}input`;
        const key = `${i}square`;
        row.push(<Square key ={key} value={val}/>);

    }
    return (row);
}

class Box extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            squares: Array(9).fill(null),
            xIsNext: true,
        };
    }
    render(){
        let board =[];
        for( let i=0; i<3;i++){
            const key = `${i}row`;
            board.push( <Row  key={key} value={i}/>);
            console.log(i)
        } 
        return (board);
    }
} 
ReactDOM.render(
    <Box />,
    document.getElementById('root')
  );

3 个答案:

答案 0 :(得分:2)

在这里您需要移动key属性:

board.push(<div key={i}><Row /></div>);

因为key应该在数组中每个元素的外部元素中

答案 1 :(得分:0)

您应该在父元素中使用键,即div在您的示例中:

for( let i=0; i<3;i++){
  board.push(<div key={i}><Row /></div>);
}

顺便说一句,您可以简单地使用:

for( let i=0; i<3;i++){
  board.push(<Row key={i} />);
}

最佳做法是使用一些字符串而不是分配数字值,这样它就不会与元素的其他键冲突:

for( let i=0; i<3;i++){
  board.push(<Row key={'row-'+i} />);
}

答案 2 :(得分:0)

关键道具应位于迭代的第一个元素上,即div元素:

board.push(<div key={i}><Row /></div>);

还请注意,for( let i=props.key*3;i<(props.key+3);i++)这行可能对您不起作用,因为没有更多的关键道具。

您可以将其更改为:for( let i=0;i<3;i++)

请注意,使用index作为键是 Anti-Pattern

  

密钥是React用来识别DOM元素的唯一东西。什么   如果将项目推到列表中或删除其中的内容,则会发生   中间?如果密钥与之前相同,则React假定DOM   元素表示与以前相同的组件。但这不再是   是的。

取自This medium - Index as a key is an anti-pattern

编辑:

添加了应为您运行的示例代码。

注意,我已删除了Row组件,因为它看起来很多余。

我不明白为什么需要两个for循环?您需要9个输入还是3个输入?

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function Square(props) {
  return (<input type='text' id={props.key} value={props.value}></input>);
}

class Box extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      squares: Array(9).fill(null),
      xIsNext: true,
    };
  }
  render() {
    let board = [];
    for (let i = 0; i < 3; i++) {
      const key = `${i}row`;
      board.push(<Square key={key} value={i} />);
      console.log(i)
    }
    return (board);
  }
}
ReactDOM.render(
  <Box />,
  document.getElementById('root')
);