reactjs setState对象列表中的多个值

pu82cl6c  于 2022-11-29  发布在  React
关注(0)|答案(3)|浏览(147)

我有一个问题,我不知道如何解决它。所以我有一个组件,我在其中声明了一个对象数组。我想单独设置它的状态,但我不想声明多个useStates。
我有一个对象数组,如下所示:

const [card, setCard] = useState({
    name: "",
    questions: [
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
      {
        question: "",
        answer: "",
      },
    ],
  });

组件如下:

const NewCard = () => {
  const handleNameChange = (event) => {
    setCard({ name: event.target.value, ...questions });
  };
  return (
    <div className="newcard-container">
      <div className="card-container">
        <h3>Podaj nazwe fiszki</h3>
        <input type="text" value={card.name} />
      </div>
      <div className="questions-container">
        {card.questions.map((q) => {
          return (
            <div className="question">
              <h4>Podaj pytanie </h4>
              <input type="text" value={q.question} />
              <h4>Podaj odpowiedź</h4>
              <input type="text" value={q.answer} />
            </div>
          );
        })}
        <button>Dodaj pytanie</button>
      </div>
    </div>
  );
};

我试着找出如何改变setState来获得这种方法,但是我没有成功。有什么想法吗?

guicsvcw

guicsvcw1#

再次,不确定这是否是你所需要的,所以让我知道。

import React, { useState, useCallback } from 'react';

export function App() {
  const [card, setCard] = useState({
    name: "",
    questions: [
      {
        id: 'question-1',
        question: "Question 1",
        answer: "",
      },
      {
        id: 'question-2',
        question: "Question 2",
        answer: "",
      },
      {
        id: 'question-3',
        question: "Question 3",
        answer: "",
      },
    ]
  });

  const handleCardNameChange = useCallback((ev) => {
    setCard((c) => ({ ...c, name: ev.target.value }))
  }, [setCard]);

  const handleAnswerChange = useCallback((cardId, value) => {
    const updatedQuestions = card.questions.map((c) => {
       
      if (c.id !== cardId) {
        return c;
      }

      return {
        ...c,
        answer: value,
      }
    });

    setCard({
      ...card,
      questions: updatedQuestions,
    })
  }, [card, setCard]);

  return (
    <div>
      <input placeholder="Card Title" value={card.name} onChange={handleCardNameChange} />
      {card.questions.map((c) => (
        <div key={c.id}>
          <p>Q: {c.question}</p>
          <input placeholder="Answer" value={c.answer} onChange={(ev) => handleAnswerChange(c.id, ev.target.value)} />
        </div>
      ))}
    </div>
  );
}

这分别处理每个问题的答案更改和卡片标题更改。我在网上的一个奇怪的编辑器中写了这个,所以它可能不完美,但应该可以工作。

sycxhyv7

sycxhyv72#

它应该

setCard((card) => { ...card , name: event.target.value });
bihw5rsg

bihw5rsg3#

您有几种方法可以做到这一点。

const [ card, setCard ] = useState( {
      name: "",
      questions: {
        1: {
          statement: "",
          answer: "",
        },
        2: {
          statement: "",
          answer: "",
        },
        //...
      }
    } );

    // To set an especifique answer or question, you can set the state like this:
    setCard( prev => ( {
      ...prev,
      questions: {
        ...prev.questions,
        1: {
          ...prev.questions[ 1 ],
          answer: "New answer"
        }
      }
    } ) );

    // To add a new question, you can set the state like this:
    setCard( prev => ( {
      ...prev,
      questions: {
        ...prev.questions,
        [ Object.keys( prev.questions ).length + 1 ]: {
          statement: "",
          answer: "",
        }
      }
    } ) );

    // To remove a question, you can set the state like this:
    setCard( prev => {
      const questions = { ...prev.questions };
      delete questions[ 1 ];
      return {
        ...prev,
        questions
      };
    } );

但是如果你想使用数组,你可以这样做:

// Solution with array
    const [card, setCard] = useState({
      name: "",
      questions: [
        {
          question: "",
          answer: "",
        },
        {
          question: "",
          answer: "",
        },
        //...
      ],
    } );

    // To set an especifique answer or question, you will need the index of the question, or null to set a new question.

    const setCardQuestions = ( index, question, answer ) => {
      setCard( ( prev ) => {
        const questions = [...prev.questions];
        if ( index === null ) {
          questions.push( {
            question,
            answer,
          } );
        } else {
          questions[ index ] = {
            question,
            answer,
          };
        }
        return {
          ...prev,
          questions,
        };
      });
    };

    // To remove a question, you will need the index of the question.
    const removeCardQuestion = ( index ) => {
      setCard( ( prev ) => {
        const questions = [...prev.questions];
        questions.splice( index, 1 );
        return {
          ...prev,
          questions,
        };
      });
    }

相关问题