Обновление значений с помощью React Hooks - PullRequest
2 голосов
/ 05 мая 2020

Правильно ли я обновляю "фрукты"? Я бы подумал, что fruit.pu sh ('something') вызовет хук useEffect? или использование setFruits приведет к повторному рендерингу?

const Fruits = () => {
const [fruitInput, setFruitInput] = useState("")
const [fruits, setFruits] = useState(['Apple', 'Orange'])

const addFruit = fruit => {
   console.log('addFruit', fruit)
   fruits.push(fruit)
   setFruits(fruits)
}

useEffect(() => {
   console.log('fruits was updated', fruits)
 }, [fruits])

 return (
 <>
    <ul>{fruits.map((fruit, index) => <li key={index}>{fruit}</li>)}</ul>
    <input type="text" onChange={ e => setFruitInput(e.target.value) } value={fruitInput} />
    <button onClick={() => addFruit(fruitInput)}>Add Fruit</button>
 </>
)
}

Ответы [ 3 ]

5 голосов
/ 05 мая 2020

Вы изменяете массив fruits на месте, поэтому React не видит его изменений и не запускает рендеринг. Вместо этого добавьте элемент во вновь созданный массив:

const addFruit = fruit => {
   console.log('addFruit', fruit)
   setFruits([...fruits, fruit])
}
3 голосов
/ 05 мая 2020

Вы должны правильно использовать setFruits. Рефакторинг

   console.log('addFruit', fruit)
   fruits.push(fruit)
   setFruits(fruits)
}

на

const addFruit = fruit => {
   console.log('addFruit', fruit)
   setFruits(fruits=>([...fruits, fruit]))
}
1 голос
/ 05 мая 2020

Реализация ниже должна решить вашу проблему: -

const Fruits = () => {
  const [fruitInput, setFruitInput] = useState("");
  const [fruits, setFruits] = useState(["Apple", "Orange"]);

  const addFruit = () => {
    const newFruits = [...fruits];
    newFruits.push(fruitInput);
    setFruits(newFruits);
    console.log(newFruits);
  };

  useEffect(() => {
    console.log("fruits was updated", fruits);
  }, [fruits]);

  return (
    <>
      <ul>
        {fruits.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
      <input
        type="text"
        onChange={e => setFruitInput(e.target.value)}
        value={fruitInput}
      />
      <button onClick={addFruit}>Add Fruit</button>
    </>
  );
};

Объяснение:

Когда вы используете [fruits] в useEffect, тогда выполняется глубокое сравнение, поэтому вы должны убедиться, что новое значение в fruits отличается от того, что было раньше. Простое нажатие значения в массиве не приведет к обновлению.

...