为啥 getElementsByClassName 在 React 的功能组件中返回 undefined?

Posted

技术标签:

【中文标题】为啥 getElementsByClassName 在 React 的功能组件中返回 undefined?【英文标题】:Why is getElementsByClassName returning undefined in React's functional component?为什么 getElementsByClassName 在 React 的功能组件中返回 undefined? 【发布时间】:2022-01-03 09:31:40 【问题描述】:

在我使用 React.js 的应用程序中的一个功能组件中,调用 getElementsByClassName 会返回“未定义”,显然,有一个带有 className 的部分标记。

import React from 'react';
import Expansion from './Expansion';

// ExpansionView refers to the container box that displays individual expansion boxes
const ExpansionView = (props) => 

const validExpansion = [
    "Classic", "Naxxramas", "Goblins vs Gnomes", "Blackrock Mountain", "The Grand Tournament", 
    "The League of Explorers", "Whispers of the Old Gods", "One Night in Karazhan", "Mean Streets of Gadgetzan",
    "Journey to Un'Goro", "Knights of the Frozen Throne", "Kobolds & Catacombs", "The Witchwood", 
    "The Boomsday Project", "Rastakhan's Rumble", "Rise of Shadows", "Saviors of Uldum", "Descent of Dragons",
    "Galakrond's Awakening", "Ashes of Outland", "Scholomance Academy", "Madness At The Darkmoon Faire",
    "Forged in the Barrens", "United in Stormwind",
];
// length is 24


//create a function that will filter by validExpansion and create an Expansion component
const expansionGenerator = (props) => 
    const expansionViewTag = document.getElementsByClassName('expansionView')[0];


    for (let i = 0; i < validExpansion.length; i += 1) 
        expansionViewTag.appendChild(
           <Expansion key=props.expansion[validExpansion[i]] selectExpansion=props.selectExpansion/>
        )
    
    return 
    // return <Expansion expansion=props.expansion selectExpansion=props.selectExpansion/>




return(
    
    <section className='expansionView'>
         expansionGenerator(props)   
        </section>
        

    )


 
export default ExpansionView;

循环的2个原因:

    在return语句中写24次并不理想。(因此要追加) 为 each 分配 props,props 将只是数组 validExpansion 中的每个元素。

请帮我提供一个有效的解决方案,谢谢!

【问题讨论】:

【参考方案1】:

因为当您最初渲染并且 React 没有向 DOM 提交任何内容时,className='expansionView' 类名在 document 中还不存在。

在 React 中,直接操作 DOM 是一种反模式,例如通过 id/class/etc 获取元素并将子节点附加到它。

如果你想遍历数组结构并渲染 JSX,那么使用 map 函数来迭代数组并将每个元素映射到某个 JSX。

const ExpansionView = ( expansion, selectExpansion ) => 
  const validExpansion = [
    "Classic", "Naxxramas", "Goblins vs Gnomes", "Blackrock Mountain", "The Grand Tournament", 
    "The League of Explorers", "Whispers of the Old Gods", "One Night in Karazhan", "Mean Streets of Gadgetzan",
    "Journey to Un'Goro", "Knights of the Frozen Throne", "Kobolds & Catacombs", "The Witchwood", 
    "The Boomsday Project", "Rastakhan's Rumble", "Rise of Shadows", "Saviors of Uldum", "Descent of Dragons",
    "Galakrond's Awakening", "Ashes of Outland", "Scholomance Academy", "Madness At The Darkmoon Faire",
    "Forged in the Barrens", "United in Stormwind",
  ];

  return (
    <section className='expansionView'>
      validExpansion.map(value => (
        <Expansion key=expansion[value] selectExpansion=selectExpansion/>
      ))   
    </section>
  );
;

【讨论】:

谢谢。但是,如果我像您编码的那样映射它,它将返回数组的副本(当然,带有映射的元素)。我希望使用 for 循环在节标记中编写多个 ,而不是其元素为 的数组。数组会一样吗?我还不能可视化/测试这个想法,因为我必须编辑 css 才能可视化,因此先问你。谢谢 @JoonK 你能澄清一下“使用for循环在部分标签中写入多个&lt;Expansion /&gt;”是什么意思吗?如果你想要一堆 Expansion 组件渲染到 DOM 中,那么“返回一个元素为 &lt;Expansion /&gt; 的数组”是 React 的方式。 是的,你是对的。我的意思是“调用多个扩展组件(它是一个直接子组件)24 次(validExpansion 数组的长度)”。我很惊讶我们可以使用数组。很久以前阅读所有主要概念部分和钩子时,我还没有在官方文档中看到它。如果您能指出我的来源以便我可以了解更多信息,那就太好了。如果没有,谢谢,您的回答让我可以进一步编码:) @JoonK 它可以是一个包含数千个要映射的值的数组,React/JSX 可以处理它。一个好的起点可能是Lists and Keys 文档,它通过渲染/返回数组介绍了一些 React 基础知识。

以上是关于为啥 getElementsByClassName 在 React 的功能组件中返回 undefined?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 javascript 命令不执行?

js为啥根据id就可以找到容器里的子元素,而根据类名就找不到?

getElementsByClassName() 有两个类

getElementsByClassName( )方法

IE8 兼容 getElementsByClassName

兼容性比较好的getElementsByClassName函数