简体   繁体   中英

list.map is not a function help create-react-app

Hi could someone tell me why I am getting the list.map is not a function error? I am pretty sure my React code makes list an array but I am a beginner so I may have overlooked something

import React, { useState, useEffect } from "react";
import Task from "./Task";

function Home() {  
  const [text, setText] = useState("");
  const [task, setTask] = useState("");
  const [list, setList] = useState([]);

  useEffect(() => {
    setList(list.push(task));
  }, [task]);

  const addTask = (e) => {
    e.preventDefault();
    setTask(text);
    setText("");
  };

  const updateText = (e) => {
    setText(e.target.value);
  };

  return (
    <div className="Home">
      <h3>Home Page</h3>
      <form onSubmit={addTask}>
        <input type="text" value={text} onChange={updateText} />
        <button type="submit">Add</button>
      </form>
      <div className="listoftasks">
        {list.map((t) => (
          <Task
            text={t}            
          />
        ))}
      </div>
    </div>
  );
}

export default Home;

Array.push() does not return the updated array. Therefore you should use Array.concat() -

useEffect(() => {
    setList(list.concat(task));
  }, [task]);

Or use spread operator, for immutability functional approach:

  useEffect(() => {
      setList([...list, task]);
  }, [task]);

When task is updating you're setting the new value of list to the result of push which is the new length of the array.

You should push and then update the state

  useEffect(() => {
    list.push(task);
    setList(list.slice());
  }, [task]);

Array.push() returns a number, the new length of the now modified in place array.

useEffect(() => setList(list.push(newThing))) // list is now a number!!!

You've turned list into a number, so now for a 3 item array(that once was 2 items) you'll be calling 3.map() and a 3 doesn't have a map method on it.

Worse yet if you just push and reset the reference you'll not update

useEffect(() => {
  list.push(newThing)
  setList(list) // won't update! list === list is true, and thus does not trigger render
})

You can go about updating the list a few ways by making new array and passing it with concatenation

useEffect(() => setList(list.concat(newThing)) // works

or spreading

useEffect(() => setList([...list, newThing])) // works

Once this is done, it will fail the check to see if the passed entity is the same value. This should allow the render to be triggered and your new updates to appear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM