【问题标题】:React: Rendering Extra Components in Array MapReact:在 Array Map 中渲染额外的组件
【发布时间】:2019-12-19 21:22:24
【问题描述】:

我是一名学生,刚开始做出反应。我正在创建一个思维树,其中的组件从数组中渲染出来,最终会有自己的孩子。我遇到了这个问题,其中呈现了一个额外的重复孩子(第一个孩子)。它只发生在三个之后,并且永远不会成为数据结构本身的一部分。我找不到很多类似的问题,如果您有任何想法,他们将不胜感激!

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

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

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

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

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

附加说明:我最终希望拥有多个用户并计划使用 Socket.IO 通过替换树的头部/原点来来回传递当前数据。使用 Sockets,它会根据用户的能力呈现额外的组件,然后很快就会使浏览器崩溃。

【问题讨论】:

    标签: javascript arrays reactjs socket.io


    【解决方案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>);
    }
    

    如果上面的代码解决了问题,主要问题是您对所有&lt;td&gt;s 使用相同的密钥,因为this.props.Data.Children.length 将始终相同 - 它不会随着您通过map 而改变数组中的每个元素。

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

    其他改进:

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

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

    Idea 在这里不需要唯一键。只有&lt;td&gt;s 可以。

    在尝试map 之前,我没有检查this.props.Data.Children 是否等于null,而是检查了它是否是一个数组。这样更安全,以防您不小心将 this.props.Data.Children 设置为 null 或数组以外的其他值。

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2018-10-01
        • 2020-11-24
        • 1970-01-01
        • 2018-07-21
        • 2023-04-03
        • 2020-10-10
        • 2021-06-07
        • 2016-03-06
        相关资源
        最近更新 更多