【问题标题】:How to use spread operator for nested objects in react?如何在反应中对嵌套对象使用扩展运算符?
【发布时间】:2021-01-15 13:13:42
【问题描述】:

我是 React 的新手,一直坚持在 reducer 中构建对象扩展代码。状态被存储为

{
  user: name,
  userAuth: null,
  errors: error,
  quizScores: [
    {
      quizId: 1,
      questionId: 12345,
      selectedOption: optionTwo,
      result: true,
    },
    {
      quizId: 2,
      questionId: 12345,
      selectedOption: optionTwo,
      result: true,
    }
  ]
}

在调度时,我想更新状态以将对象(如下)附加到位于“quizScores”中的其他对象

{
  quizId: 2,
  questionId: 12345,
  selectedOption: optionTwo,
  result: true,
}

我正在尝试的是:

case ADD_SCORE:
    return {
      ...state,
      quizScores:{...state[quizScores],action.payload}
    };

很高兴了解如何使用扩展运算符复制以前的对象以及如何将新对象附加到其中。如果您认为,我可以使用更好的结构来存储数据,我也将不胜感激。我的目标是简单地继续添加所有问题性能以存储在状态中。 谢谢!!

我正在使用 useState 钩子在功能组件中创建 quizScores 数据并触发以下函数调用 (handleQuizScore):

  const handleQuizScore = (questionData) => {
    dispatch({
      type: ADD_SCORE,
      payload: questionData,
    });
  };

这是处理状态的整个reducer函数:

const authReducer = (state, action) => {
  switch (action.type) {
    case SUCCESS_REGISTER:
    case FAIL_REGISTER:
      return {
        ...state,
        userAuth: null,
        errors: action.payload,
      };
    case SUCCESS_LOGIN:
      localStorage.removeItem("token");
      localStorage.setItem("token", action.payload.token);
      console.log(action.payload.token);
      return {
        ...state,
        userAuth: true,
        errors: null,
      };
    case FAIL_LOGIN:
      return {
        ...state,
        userAuth: null,
        errors: action.payload,
      };
    case SET_ERROR:
      return {
        ...state,
        errors: action.payload,
      };
    case CLEAR_ERROR:
      return {
        ...state,
        errors: null,
      };
    case SET_USER:
      return {
        ...state,
        user: action.payload,
        userAuth: true,
        errors: null,
      };
    case AUTH_ERROR:
      return {
        ...state,
        errors: action.payload,
        userAuth: null,
      };
    case LOG_OUT:
      localStorage.removeItem("token");
      return {
        ...state,
        userAuth: null,
        errors: action.payload,
      };
    case ADD_SCORE:
      return {
        ...state,
        quizScores: [...state.quizScores, action.payload],
      };
    default:
      return state;
  }
};

使用useState的功能组件:

const QuizQuestion = (props) => {
  const { clearError, userAuth, user, handleQuizScore } = useContext(
    AuthContext
  );
  let [questionData, handleQuizQuestion] = useState({
    selectedOption: "",
    result: "",
    quiz: "",
    questionId: "",
  });

  let { selectedOption, result, quiz, questionId } = questionData;
  const { question, toggleIsAnswered, quizId } = props;

  const handleOptionChange = (e) => {
    const { value } = e.target;
    console.log(question.answer);
    handleQuizQuestion({
      ...questionData,
      quiz: quizId,
      questionId: question._id,
      selectedOption: value,
    });
  };

  const resultCheck = (questionData) => {
    let flag = selectedOption === question.answer ? "true" : "false";
    handleQuizQuestion({
      ...questionData,
      result: flag,
    });
  };
  const handleVote = async (e) => {
    e.preventDefault();
    resultCheck(questionData);
    console.log("handleQuizQuestion", questionData);
    await handleQuizScore(questionData);
    toggleIsAnswered();
  };

返回(等等)

【问题讨论】:

  • 为什么quizScores不是一个数组,而是一个对象?
  • 使用点符号{ ...state.quizScores, action.payload };
  • 同意@Tobi,您的状态形状似乎不是有效的语法。
  • @Tobi 感谢 Tobi 和善良的用户和 Drew !我已经把它改成了一个数组。
  • @Ravi 你在函数组件中哪里使用了useState和useDispatch?

标签: javascript reactjs ecmascript-6


【解决方案1】:

state[quizScores] 表示获取变量quizScores,对其求值,并将该值用作对象state 的键。 quizScores 可能未定义。使用字符串文字作为键 state["quizScores"] 或更常见且更可取的点表示法 state.quizScores 来访问和传播该数组值。

case ADD_SCORE: 
  return {
    ...state,
    quizScores: [...state.quizScores, action.payload],
  };

【讨论】:

  • 感谢您的回答和变量的解释。这是我今天刚刚发现的一个很棒的社区。使用上述结构时,我收到错误“TypeError:state.quizScores is not iterable”。据我了解,'quizScores' 是一个数组,用于存储一系列对象,例如 { quizId: 2, questionId: 12345, selectedOption: optionTwo, result: true, }
  • @Ravi 你使用的是 react-redux 还是 useReducer react 钩子?您介意更新您的问题以包含您的 整个 reducer 函数和初始状态,以及它处理的任何动作创建者吗?似乎(a)您在问题中的初始状态不同,或者(b)您的状态形状随着时间的推移而发生变化。
  • 我刚刚更新了问题以包括减速器功能。我在功能组件中使用 useState 挂钩来创建数据对象,我试图将其附加到 reducer 函数中的 quizScores 数组以生成状态。
  • @Ravi 谢谢。您还可以准确地复制/粘贴您传递给减速器函数的初始状态吗?
  • 非常感谢您的帮助。我刚刚也粘贴了功能组件代码,以及生成要存储在 quizScores 中的状态元素。
猜你喜欢
  • 2020-03-15
  • 2021-07-07
  • 1970-01-01
  • 2020-03-18
  • 2019-09-29
  • 2018-10-04
  • 2020-06-09
  • 2023-02-25
  • 1970-01-01
相关资源
最近更新 更多