React:在数组映射中渲染额外的组件

时间:2019-12-19 21:22:24

标签: javascript arrays reactjs socket.io

我是一名学生,是新来的人。我正在创建一个思维树,其中的组件呈现出数组之外,最终将拥有自己的子级。我遇到了一个问题,其中呈现了(第一个孩子的)另一个重复孩子。它只会在三点之后发生,并且永远不会成为数据结构本身的一部分。我找不到发布的许多类似问题,如果您有任何想法,将不胜感激!

displayChildren = () => {
        let num = 1;
        let childs = [];
        if(this.props.Data.Children == null)
            return;

        this.props.Data.Children.map(idea => { 
            childs.push(
                <td key = {'R-'+this.props.Data.Children.length}>
                    <Idea key={'I-'+this.props.Data.Children.length} Data={idea} pushToTop={this.pushToTop}/>
                </td>
            );
            console.log("Creating Child >"+ num++ +"< for "+this.props.Data.Title, childs);
        });

        console.log("FINISHED CHILDREN: ", childs);
        return(<tr align="center" valign="top">{childs}</tr>);
    }Picture: Two Children -> Working

enter image description here

图片:两个孩子的日志->数据中有两个孩子。

enter image description here

图片:三个孩子->错误,重复渲染->显示四个孩子

注意:连接基于数组的大小(三个),因此仅显示三个。

enter image description here

图片:三个孩子的日志->数据中的三个孩子

enter image description here

其他说明:我最终希望拥有多个用户,并计划使用Socket.IO通过替换树的头/原点来回传递当前数据。借助Socket,它可以将额外的组件呈现给用户,从而使浏览器立即崩溃。

2 个答案:

答案 0 :(得分:1)

您的代码还有很大的改进空间。我将从重做它开始,然后解释一些更改背后的原因。

displayChildren = () => {
  if (!Array.isArray(this.props.Data.Children)) return;

  const childs = this.props.Data.Children.map((idea, i) => {
    console.log(`Creating Child >${i}< for ${this.props.Data.Title}`, this.props.Data.Children);
    return (
      <td key = {`R-${idea.Title}`}>
        <Idea Data={idea} pushToTop={this.pushToTop}/>
      </td>
    );
  });

  console.log("FINISHED CHILDREN: ", childs);
  return(<tr align="center" valign="top">{childs}</tr>);
}

如果上述代码解决了问题,则主要的问题是您为所有<td>使用了相同的密钥,因为this.props.Data.Children.length将始终相同-它不会随您的变化而变化map遍历数组中的每个元素。

相反,我使用idea.Title为每个<td>构建(希望)唯一的密钥。您还可以使用iindex的缩写,map提供给回调函数的第二个参数,我也在内部console.log语句中使用了该参数),但是在某些情况下可能会出现问题(例如,如果要动态地添加,删除或对this.props.Data.Children数组中的元素进行排序)。

其他改进:

不要创建数组,然后在pushmap到它。无论如何,在数组上进行映射都会返回一个新数组,因此无需推送到单独的数组。

Prefer string literal syntax to string concatenation with the + symbol.

Idea在这里不需要唯一键。只有<td>个。

我没有在尝试this.props.Data.Children之前检查null是否等于map,而是检查它是否为数组。如果您不小心将this.props.Data.Children设置为null或数组之外的其他内容,这样做会更安全。

还有更多改进的空间,但这超出了此答案的范围。

答案 1 :(得分:0)

key必须是唯一的,而在您的代码中则并非如此。非唯一键可能导致像您一样的奇怪行为。请为循环中的每个<td>生成一个唯一的密钥,它将解决您的问题。

<td key = {'R-'+this.props.Data.Children.length}>