Home > OS >  Getting Cannot read properties of undefined (reading 'map')?
Getting Cannot read properties of undefined (reading 'map')?

Time:01-25

Im having trouble with this little test component what am I missing here? This is just a simple little teaser question, seems like the mapping is where is breaking. I don't know if Im passing the value down incorrectly or what

import React from "react";

export default function App() {
  const [state, setState] = React.useState({
    input: "",
    items: [],
    error: false
  });

  const { input, items, error } = state;

  const changeState = (state) => {
    return setState(state);
  };

  if (input.length > 10) {
    React.useEffect(() => {
      changeState({ error: false });
    });
  }

  const handleUpdateInput = (e) => {
    if (e.key === "Enter") {
      changeState({ items: [e.target.value, ...items] });
      changeState({ input: "" });
    }
  };

  const removeItem = (item) => {
    changeState({ items: items.filter((i) => i !== item) });
  };

  return (
    <div>
      <input
        onChange={(e) => {
          changeState({ input: e.target.value });
        }}
        value={input}
        onKeyPress={handleUpdateInput}
      />
      {items.map((item, index) => {
        return (
          <div key={index}>
            {item} <span onClick={removeItem(item)}>X</span>
          </div>
        );
      })}
      {error && <div>Input is too long!</div>}
    </div>
  );
}

CodePudding user response:

When you set state using hooks, the value passed in will be the exact new state - it won't be merged with the old state if it happens to be an object, as with class components.

So, for example, you need to change

changeState({ error: false });

to

changeState({ ...state, error: false });

and do the same for everywhere else you're setting state.

But a better approach (that I'd recommend, and that React recommends) would be to use separate state variables from the beginning:

const [items, setItems] = useState([]);

Set it by changing

changeState({ items: [e.target.value, ...items] });

to

setItems([e.target.value, ...items]);

and follow that same pattern for input and error too.

CodePudding user response:

You seem not to have an items variable in you logic, and yet you are using one in your map. Try with this :

 {state.items.map((item, index) => {
        return (
          <div key={index}>
            {item} <span onClick={removeItem(item)}>X</span>
          </div>
        );
      })}
  •  Tags:  
  • Related