Home > front end >  Why is getElementsByClassName returning undefined in React's functional component?
Why is getElementsByClassName returning undefined in React's functional component?

Time:11-25

In one of my functional components in an application using React.js, calling getElementsByClassName returns 'undefined', when clearly, there is a section tag with the 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 reasons for the loop:

  1. Not ideal to write 24 times in return statement.(thus want to append)
  2. Assign props for every , and props will simply be each element in the array validExpansion.

Please help me with a valid solution, thanks!

CodePudding user response:

Because when you are initially rendering and React hasn't committed anything to the DOM the className='expansionView' classname doesn't exist in the document yet.

In React it is an anti-pattern to directly manipulate the DOM, like getting an element by id/class/etc and appending children nodes to it.

If you want to loop over an array structure and render JSX then use a map function to iterate the array and map each element to some 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>
  );
};
  • Related