reactjs 在嵌套的对象数组中使用.map()和spread运算符进行React、更新状态

4xrmg8kj  于 2022-12-03  发布在  React
关注(0)|答案(3)|浏览(200)

我还是一个React的新手,在上面提到的主题上纠结了一段时间,我的状态是这样的:

const [questions, setQuestions] = React.useState([])    
    React.useEffect(()=>{
        fetch('https://the-trivia-api.com/api/questions?limit=5&difficulty=medium').then((response)=>response.json()).then((data)=>{
            let questionsData = data.map((item) => {
                return {
                    id: nanoid(),
                    questionText: item.question,
                    answerOptions: [
                        {id: nanoid(), answerText: item.correctAnswer, isCorrect: true, selected: false,},
                        {id: nanoid(), answerText: item.incorrectAnswers[0], isCorrect: false, selected: false,},
                        {id: nanoid(), answerText: item.incorrectAnswers[1], isCorrect: false, selected: false,},
                        {id: nanoid(), answerText: item.incorrectAnswers[2], isCorrect: false, selected: false,},
                    ].sort(()=>Math.random() -0.5),
                };
            })
            setQuestions(questionsData)
            })
        
    }, [])

它是一个返回一个测验问题和4个"随机"按钮的状态。我尝试做的是更新该状态,使其中一个answerOptions(即按钮)从选中状态变为选中状态:false表示选定:真的。我确信用. map和spread运算符是可行的,但我真的对语法感到困惑
selectAnswer是由子组件的单选按钮的onChange触发的。我可以访问问题ID和每个answerOptions ID,因此访问它们不是问题。我只是不知道如何返回状态。下面是一个失败的尝试示例。

function selectAnswer(answerId, questionId){
        setQuestions(prevData => prevData.map((item)=>{
            return item.answerOptions.map((answerItem)=>{
                if(answerId === answerItem.id) {
                    return {...item, [answerOptions[answerItem].selected]: !answerOptions[answerItem].selected}
                } else return {...item}
            })
        }))
        }

提前感谢您抽出宝贵时间

xfb7svmp

xfb7svmp1#

为了更新组件的状态以将其中一个answerOptions的selected属性设置为true,可以使用map方法迭代状态中的现有问题,找到具有匹配id的answerOption,然后更新其selected属性。可以使用spread运算符(...)为每个问题创建一个新对象,其中包含更新后的answerOption。
下面是一个如何在selectAnswer函数中实现此功能的示例:

function selectAnswer(answerId, questionId) {
  setQuestions(prevData =>
    prevData.map(question => {
      // Create a new array of answerOptions for this question,
      // with the selected answerOption updated to have its selected property set to true.
      const answerOptions = question.answerOptions.map(answerOption => {
        if (answerOption.id === answerId) {
          return { ...answerOption, selected: true };
        } else {
          return answerOption;
        }
      });

      // Return a new object for this question with the updated answerOptions array.
      return { ...question, answerOptions };
    })
  );
}

在此示例中,selectAnswer函数使用map方法迭代状态中的现有问题。对于每个问题,它都创建一个新的answerOptions数组,并更新具有匹配id的answerOption,以将其selected属性设置为true。然后,它为具有更新的answerOptions数组的问题返回一个新对象。

35g0bw71

35g0bw712#

function selectAnswer(answerId, questionId) {
  setQuestions((prevData) =>
    prevData.map((item) => ({
      ...item,
      answerOptions: item.answerOptions.map((answerItem) => ({
        ...answerItem,
        selected: answerId === answerItem.id,
      })),
    }))
  );
}
mgdq6dx1

mgdq6dx13#

与最初的问题没有直接关系,但我建议您阅读react文档的这一部分,了解如何使用useEffect获取数据

相关问题