list.map не является функцией help create-response-app - PullRequest
2 голосов
/ 30 апреля 2020

Привет, может кто-нибудь сказать мне, почему я получаю list.map не является ошибкой функции? Я почти уверен, что мой код React делает список массивом, но я новичок, поэтому я мог что-то пропустить

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;

Ответы [ 4 ]

5 голосов
/ 30 апреля 2020

Array.push() не возвращает обновленный массив. Поэтому вы должны использовать Array.concat() -

useEffect(() => {
    setList(list.concat(task));
  }, [task]);
4 голосов
/ 30 апреля 2020

Или используйте оператор распространения для функционального подхода с неизменяемостью:

  useEffect(() => {
      setList([...list, task]);
  }, [task]);
0 голосов
/ 30 апреля 2020

Array.push() возвращает число, новую длину теперь модифицированного массива на месте.

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

Вы превратили список в число, так что теперь для массива из 3 элементов (который когда-то был 2 элемента) вы будете звонить 3.map(), а 3 не имеет метода карты.

Еще хуже, если вы просто наберете pu sh и сбросите ссылку, которую вы не обновите

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

Вы можете go обновить список несколькими способами, создав новый массив и передав его с конкатенацией

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

или распространяя

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

Как только это будет сделано, проверка не пройдет, чтобы увидеть, является ли переданный объект тем же значением. Это должно позволить запустить рендер и появиться ваши новые обновления.

0 голосов
/ 30 апреля 2020

Когда task обновляется, вы устанавливаете новое значение list в результате push, который является новой длиной массива.

Вы должны pu sh, а затем обновить состояние

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