1

I am trying to fill the dropdown with the data from the given array 'options' but I'm running into an error where it cannot read property appendChild of null.

If I use 'document.getElementByClassName' instead of document.getElementById for 'select', I run into an error where 'select.appendChild is not a function'

works on codepen but does not work in my react function. https://codepen.io/michaellee212/pen/LYpGgrm

I can't figure out why this problem happens

code:

    export default function ComposeEmailForm({ handleCompose, template_titles }) {

    var options = ['1', '2', '3', '4', '5'];

        var select = document.getElementById('template-select');
        for (var i = 0; i < options.length; i++) {
            var opt = options[i];
            var el = document.createElement('option');
            el.text = opt;
            el.value = opt;
            console.log(el);
            select.appendChild(el);
        }

    return (
        <select id='template-select'>
                    <option>----</option>
                </select>
)

2 Answers 2

4

The beauty of React and JSX is that you don't have to do DOM manipulation like this. In fact, you shouldn't be doing things like this. Instead you can use your array of options to create the <option>s in JSX, like this:

export default function ComposeEmailForm({ handleCompose, template_titles }) {
  const options = ['1', '2', '3', '4', '5'];

  return (
    <select id='template-select'>
      <option>----</option>
      {options.map(option => <option key={option} value={option}>{option}</option>)}
    </select>
  );
}

Let me know if that helps at all.

Sign up to request clarification or add additional context in comments.

2 Comments

interesting solution. I didn't know you could do that with react. Although I am experiencing a syntax solution at the end with } where it says '.' expected. Not sure why that is
Ah, sorry, I missed the end parenthesis for the options map, fixed the code now. This is exactly what React is for, if you find yourself reaching for document.getElementById or document.createElement then you are probably working against React.
0

The select tag in return is not a real dom element, it will become a real dom element after some processing in react, then you can use document.getElementByClassName ('template-select') to find it. For the error you encountered, you can fix it like this.

import React,{useEffect} from 'react'
export default function ComposeEmailForm({ handleCompose, template_titles }) {
  useEffect(()=>{
    var options = ['1', '2', '3', '4', '5'];

    var select = document.getElementByClassName('template-select');
    for (var i = 0; i < options.length; i++) {
        var opt = options[i];
        var el = document.createElement('option');
        el.text = opt;
        el.value = opt;
        console.log(el);
        select.appendChild(el);
    }
  },[])

  return (
    <select id='template-select'>
                <option>----</option>
            </select>
)

UseEffect is used here, it will run after the select becomes true dom element.

You can learn about the life cycle of react and some knowledge of react hooks.

The componentDidMount() method runs after the component output has been rendered to the DOM. -- https://reactjs.org/docs/state-and-lifecycle.html

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined. -- https://reactjs.org/docs/hooks-effect.html

1 Comment

this solution worked with useEffect hook. I also had to change to document.getElementById.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.