简体   繁体   English

如何将 React 函数式组件转换为类组件

[英]How to Convert React Functional Components into Class Components

I've been trying to convert below code to class components but the results i get is not same.我一直在尝试将下面的代码转换为类组件,但我得到的结果不一样。 please help.请帮忙。 Especially when i need to convert useMemo.特别是当我需要转换 useMemo 时。 In this case, i don't know what the function of useMemo please someone can tell me.在这种情况下,我不知道 useMemo 的功能是什么,请有人告诉我。 What i know is useMemo is a Hook.我所知道的是 useMemo 是一个 Hook。 And hook can't be used in class components.并且钩子不能用在类组件中。 so how can i convert it?那么我该如何转换呢? All i need is to convert all the below code into react class components.我需要的只是将以下所有代码转换为反应类组件。

import React, { useState, useMemo } from "react";
import "./styles.css";
const initialQuestions = [
  {
    id: 1,
    questionText: "What is the capital of France or Ireland?",
    questionType: "checkbox",
    answerOptions: [
      { answerText: "New York", isCorrect: false, checked: false },
      { answerText: "London", isCorrect: false, checked: false },
      { answerText: "Paris", isCorrect: true, checked: false },
      { answerText: "Dublin", isCorrect: true, checked: false }
    ]
  },
  {
    id: 2,
    questionText: "Who is CEO of Tesla or Amazon?",
    questionType: "select",
    answerOptions: [
      { answerText: "Jeff Bezos", isCorrect: true, checked: false },
      { answerText: "Elon Musk", isCorrect: true, checked: false },
      { answerText: "Bill Gates", isCorrect: false, checked: false },
      { answerText: "Tony Stark", isCorrect: false, checked: false }
    ]
  },
  {
    id: 3,
    questionText: "The iPhone was created by which company?",
    questionType: "select",
    answerOptions: [
      { answerText: "Apple", isCorrect: true, checked: false },
      { answerText: "Intel", isCorrect: false, checked: false },
      { answerText: "Amazon", isCorrect: false, checked: false },
      { answerText: "Microsoft", isCorrect: false, checked: false }
    ]
  }
];

const App = () => {
  const [currentQuestion, setCurrentQuestion] = useState(0);
  const [showScore, setShowScore] = useState(false);
  const [questions, setQuestions] = useState(initialQuestions);

  const handleAnswerOptionClick = (e, questionId) => {
    const answerTextValue = e.target.value;
    const updatedQuestions = questions.map((question) => {
      if (question.id === questionId) {
        const updatedAnswersOptions = question.answerOptions.map((answer) => {
          if (answer.answerText === answerTextValue) {
            return { ...answer, checked: !answer.checked };
          } else {
            return question.questionType === "select"
              ? { ...answer, checked: false }
              : answer;
          }
        });
        return { ...question, answerOptions: updatedAnswersOptions };
      } else {
        return question;
      }
    });
    setQuestions(updatedQuestions);
  };

  const score = useMemo(() => {
    return questions.reduce((acc, q) => {
      const correctAnswerSelected = q.answerOptions.reduce((acc, answer) => {
        if (answer.checked && answer.isCorrect) {
          acc = acc + 1;
        }
        return acc;
      }, 0);
      acc = acc + correctAnswerSelected;

      return acc;
    }, 0);
  }, [questions]);

  const handleNext = () => {
    const nextQuestion = currentQuestion + 1;
    if (nextQuestion < questions.length) {
      setCurrentQuestion(nextQuestion);
    } else {
      setShowScore(true);
    }
  };

  return (
    <div className="App">
      {showScore ? (
        <div>
          You scored {score} out of {questions.length}
        </div>
      ) : (
        <main className="question">
          {score}
          <div>
            <div>
              <h2>{questions[currentQuestion].questionText}</h2>
            </div>
          </div>
          <div className="question__options">
            {questions[currentQuestion].questionType === "select" &&
              questions[currentQuestion].answerOptions.map(
                (answerOption, i) => (
                  <React.Fragment key={answerOption.answerText}>
                    <input
                      type="radio"
                      name="radio-group"
                      value={answerOption.answerText}
                      checked={answerOption.checked}
                      onChange={(e) =>
                        handleAnswerOptionClick(
                          e,
                          questions[currentQuestion].id
                        )
                      }
                    />
                    <label htmlFor={i}>{answerOption.answerText}</label>
                  </React.Fragment>
                )
              )}
            {questions[currentQuestion].questionType === "checkbox" &&
              questions[currentQuestion].answerOptions.map(
                (answerOption, i) => (
                  <div key={answerOption.answerText}>
                    <input
                      className="option"
                      type="checkbox"
                      id={i}
                      value={answerOption.answerText}
                      onClick={(e) =>
                        handleAnswerOptionClick(
                          e,
                          questions[currentQuestion].id
                        )
                      }
                    />
                    <label htmlFor={i}>{answerOption.answerText}</label>
                  </div>
                )
              )}

            <div className="question__submit">
              <button onClick={handleNext}>Next</button>
            </div>
          </div>
        </main>
      )}
    </div>
  );
};

export default App;

useMemo is a hook that is used to memoize a component or function. useMemo 是一个钩子,用于记忆组件或函数。 That means that given the same input the output will be the same, since react knows that it will be the same given the same inputs it no longer has to re-render or re-calculate the function.这意味着给定相同的输入,输出将是相同的,因为 react 知道在给定相同输入的情况下它将是相同的,它不再需要重新渲染或重新计算函数。 To move it over to a classical component you just need to move the internal function over the question.reduce(...).要将其移至经典组件,您只需将内部函数移至 question.reduce(...)。 The main issue with doing this is it could slow down your application depending on how big the calculations are.这样做的主要问题是它可能会减慢您的应用程序,具体取决于计算量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM