Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Add li elements to ul on button click in React js

I am trying to add a new li element to the ul element in the CommentList return div. It should contain the user input from the <input type="text" /> field.

I am getting this error:
‘Cannot read properties of null (reading ‘value’)’

I’ve tried a few things, like creating new li elements onSubmit and appending them to the ul element but no luck.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Intended Outcome

On user click, whatever value is in the input text field, it will create a new li element and add it to the ul element.

const CommentList = (props) => {
    const [children, setChildren] = useState([]);

    setChildren((oldArray) => [
        ...oldArray,
        document.querySelector("input[type='text']").value,
    ]);

    return (<div>
        <form>
            <input type="text" />
            <input onSubmit={setChildren} type="button" value="Post" />
        </form>
        <ul>
        </ul>
    </div>);
}

>Solution :

You shouldn’t be mixing React with native DOM methods.

This example:

  1. Has one state for the list of items, and one for the current state of the input.

  2. When the value of the input changes the input state is updated.

  3. When the button is clicked the items state is updated with the input state, the input state is reset, and the input element refocused. (useRef)

(Note: using <input> without <form> is valid HTML, so that’s why we can use onClick instead of onSubmit.)

const { useState, useRef } = React;

function Example() {

  // Create a new reference which will be applied
  // to the input element
  const ref = useRef(null);

  // Initialise the states
  const [ items, setItems ] = useState([]);
  const [ input, setInput ] = useState('');

  // When the input value changes update
  // the `input` state
  function handleChange(e) {
    setInput(e.target.value);
  }

  // When the button is clicked add the
  // `input` state to the `items` state,
  // reset the `input` state, and focus on 
  // the input element
  function handleClick() {
    setItems([...items, input]);
    setInput('');
    ref.current.focus();
  }

  // `map` over the items array to produce an
  // array of list items
  return (
    <div>
      <input
        ref={ref}
        onChange={handleChange}
        value={input}
      />
      <button onClick={handleClick}>Save</button>
      <ul>{items.map(item => <li>{item}</li>)}</ul>
    </div>
  );

}

ReactDOM.render(
  <Example />,
  document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading