Не могу использовать метод pop для массива состояний в React

#javascript #reactjs

#javascript #reactjs

Вопрос:

Эй, ребята, я, должно быть, упускаю что-то маленькое, я пытаюсь удалить элемент массива из состояния, чтобы react отображал нужное количество вопросов. Моя кнопка «Больше» работает отлично, но когда я нажимаю кнопку «Меньше», все исчезает, и я получаю сообщение об ошибке: questions.map не является функцией.

 import React, { useState } from 'react' 

export default function Truefalse(props) {

    const [questions, setQuestions] =useState([1])




   return (
   <div className=''>
       {questions.map((question)=> {
           return <div style={{width: '200px', height:'200px', color: 'blue', backgroundColor:'blue', margin: '2em'}}></div>
       })}
       <button onClick={()=> setQuestions([...questions, 1])}>More</button>
       <button onClick={()=>setQuestions(questions.pop())}>Less</button>
       <h1>question: {questions.length}</h1>
   </div>
   )
}
  

Комментарии:

1. Это выглядит так: [1, 1, 1, 1]. Потому что каждый раз, когда нажимается «еще», он добавляет 1 к массиву. и это нормально, потому что мне просто нужна длина массива. Но, похоже, я не могу ничего отключить.

2. questions.pop() вернет элемент, который был удален из массива, а не массив с одним элементом меньше. Вы должны создать функцию обратного вызова, которая сначала выполняет pop, а ЗАТЕМ выполняет SetQuestions (вопросы).

Ответ №1:

У вас есть пара проблем.

  1. Вы напрямую изменяете состояние при удалении элемента
  2. Вы не используете ключи при отображении списка вопросов

Вот пример, показывающий, как удалить последний элемент, а также то, что я подразумеваю под использованием ключей при рендеринге списка. https://codesandbox.io/s/adoring-gates-vwv61?file=/src/TrueFalse.jsx

Соответствующий код:

 const remove = useCallback(() => {
  setQuestions((prev) => {
    // 1. we clone the array by destructuring
    // 2. use pop to remove last item in array
    const next = [...prev];
    next.pop();
    return next;
  });
}, [setQuestions]);

/// ...

{questions.map((question, index) => (
  <div
    key={`${question}-${index}`}
    style={{
      width: "200px",
      height: "200px",
      color: "blue",
      backgroundColor: "blue",
      margin: "2em"
    }}
  >
    {question}
  </div>
))}
  

Обратите внимание, что наша функция удаления сначала клонирует массив, а затем удаляет последний элемент, а не напрямую изменяет состояние.

Также посмотрите, как вопросы отображаются с помощью ключевого реквизита. В этом примере я использую как значение, так и индекс, поскольку использование только значения приведет к получению неуникальных ключей.