1

I am trying to figure out how to pass an item thru the state on the item: [] inside the list state. Whenever I tried this code, an error shows up as lists is not iterable whenever I insert or add item to the array

Is there a way to insert data to the array property of the state? And adding more string arrays in that property?

const [lists, setLists] = useState({
  item: [],
});

const addList = () => {
  const listItem = document.getElementById("listItem");

  if (listItem.value !== "") {
    setLists([
      ...lists,
      {
        item: listItem.value,
      },
    ]); // >>> [INSERT TO THE ARRAY PROPERTY]
    listItem.value = "";
  }
};

return (
  <div>
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        id="listItem"
        name="item"
        onKeyPress={(e) => (e.key === "Enter" ? addList() : null)}
      />
      <button
        type="button"
        onClick={() => {
          addList();
        }}
      >
        Add
      </button>

      <ul>
        LIST
        {lists.item.map((val, index) => {
          return (
            <li key={index}>
              <p>{val}</p>
              <button type="button" onClick={() => removeList(index)}>
                Remove
              </button>
            </li>
          );
        })}
      </ul>
      <button type="submit">submit</button>
    </form>
  </div>
);

2 Answers 2

4
  • You seem to be having some confusion regarding your data types. lists is an array of objects of the shape {item: ...}.
    • The useState call should be useState([]).
    • You'll need lists.map(({item}, index) => (or lists.map(val and val.item) to get at the ....
    • You can use e.g. console.log(lists), or a debugger, to see what's really happening.)
  • You shouldn't use document.getElementById() with React, ever. Instead, make the input controlled (or have a ref to it and read the value if you want uncontrolled, but you likely don't).
  • The setLists call should be the functional form: setLists(lists => [...lists, {item: listItem.value}]).

All in all, something like

function Component() {
  const [newItemText, setNewItemText] = React.useState("");
  const [todoList, setTodoList] = React.useState([]);

  const addList = (event) => {
    event.preventDefault();
    if (newItemText !== "") {
      setTodoList(todoList => [
        ...todoList,
        {
          item: newItemText,
        },
      ]);
      setNewItemText("");
    }
  };
  


  return (
    <div>
      <form onSubmit={addList}>
        <input
          type="text"
          name="item"
          value={newItemText}
          onChange={e => setNewItemText(e.target.value)}
        />
        <button
          type="submit"
        >
          Add
        </button>
      </form>

      <ul>
        LIST
        {todoList.map(({item}, index) => {
          return (
            <li key={index}>
              <p>{item}</p>
              <button type="button">
                Remove
              </button>
            </li>
          );
        })}
      </ul>
    </div>
  );
}

ReactDOM.render(<Component />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
<div id="root">

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

2 Comments

I'm still pretty new on using React and trying to understand how they work. This was a test code for me and the reason why I did not use 'useState([])' is because I wanted to make the lists that contain set of objects inside like 'useState( { id:"", name: "", item: [] } )' where I can pass to the item:[] from that state
Your state isn't semantically "lists", though. If you wanted multiple to-do lists each with multiple items, then you'd want something like useState([{id: "list1", name: "Chores", items: [{id: "item1", text: "Take out the trash"}]}]) – that way it makes sense that lists is an array of lists.
1
const [lists, setLists] = useState({
  item: [],
});

In the code above you set initial value as an Object not an Array. Try to change code like below.

 const [lists, setLists] = useState([]);

1 Comment

I tried this method but this is not exactly what I was looking for because I am trying to put several objects inside that state where 'item:[]' has already been declared. So an example would be like 'useState({name: "", item:[]})' .etc

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.