Компонент React с переключателями повторно отображает значение, возвращающее значение null

#javascript #reactjs #radio-button

Вопрос:

Я визуализирую страницу анкеты, на которой показан компонент вопроса со следующими атрибутами: Номер вопроса, текст вопроса и 5 переключателей, на каждом из которых есть ответ.

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

Я столкнулся с проблемой, когда, как только мой компонент отображается, и я нажимаю на ответ, кажется, что он повторно отображается, и мой переключатель выбора кажется, что он не был нажат.

Это моя страница с вопросами, на которой я вставляю компонент вопросов

   const Questionaire = (props) => {

  const [answers, set_answers] = useState({});

  console.log("Inside Questionaire component", answers);

  const onChangeAnswerFunc = (answer, match) => {
    set_answers({ ...answers, [match.params.questionNumber]: answer });
  };

  return (
    <div className="quiz">
      <Route
        path="/dashboard/questions/:questionNumber"
        component={({ match }) => (
          <Question
            questionNumber={match.params.questionNumber}
            answerFunc={(e) => onChangeAnswerFunc(e, match)}
          />
        )}
      />
    </div>
  );
};

export default Questionaire;
 

И это мой вопрос.

 const Question = ({ omat, pmat, cmat, questionNumber, answerFunc }) => {
  const [currentRadioValue, setRadioValue] = useState(null);
  useEffect(() => {
    if (currentRadioValue != null) {
      answerFunc(currentRadioValue);

      console.log("Inside useEffect");
    }
  }, [currentRadioValue, answerFunc]);

  const onChange = (e) => {
    setRadioValue(e.target.value);
    // handleChange();
    // console.log("onChange");
  };
  console.log("Under on change", currentRadioValue);

  const handleChange = () => {
    answerFunc(currentRadioValue);
  };

  // console.log(currentRadioValue);

  const onSubmit = async (e) => {
    e.preventDefault();
  };

  if (!omat) return null;
  const question = omat[questionNumber];
  const {
    question: text,
    section,
    subject,
    score0,
    score25,
    score50,
    score75,
    score100,
  } = question;

  const anyQuestion = (
    <Link to={`/dashboard/questions/${Number(questionNumber)   1}`}>Next</Link>
  );
  const finalQuestion = <button>Submit</button>;

  const previousQuestion = (
    <Link to={`/dashboard/questions/${Number(questionNumber) - 1}`}>
      Previous
    </Link>
  );

  return (
    <div>
      <div className="questions">
        <h2 className="lead">Question number: {questionNumber} / 40 </h2>
        <p className="question-section">Section: {section}</p>
        <p className="question-subject">Subject: {subject}</p>
        <div>{text}</div>
        <form className="form" onSubmit={(e) => onSubmit(e)}>
          <div className="form-group">
            <>
              <input
                type="radio"
                name={`Radio`}
                value="Radio - 1"
                checked={currentRadioValue === `Radio - 1`}
                onChange={(e) => onChange(e)}
              />
              <label> - {score0}</label>
            </>
          </div>
          <div className="form-group">
            <>
              <input
                type="radio"
                name={`Radio`}
                value="Radio - 2"
                checked={currentRadioValue === `Radio - 2`}
                onChange={(e) => onChange(e)}
              />
              <label> - {score25}</label>
            </>
          </div>
          <div className="form-group">
            <>
              <input
                type="radio"
                name={`Radio`}
                value="Radio - 3"
                checked={currentRadioValue === `Radio - 3`}
                onChange={(e) => onChange(e)}
              />
              <label> - {score50}</label>
            </>
          </div>
          <div className="form-group">
            <>
              <input
                type="radio"
                name={`Radio`}
                value="Radio - 4"
                checked={currentRadioValue === `Radio - 4`}
                onChange={(e) => onChange(e)}
              />
              <label> - {score75}</label>
            </>
          </div>
          <div className="form-group">
            <>
              <input
                type="radio"
                name={`Radio`}
                value="Radio - 5"
                checked={currentRadioValue === `Radio - 5`}
                onChange={(e) => onChange(e)}
              />{" "}
              <label> - {score100}</label>
            </>
          </div>
        </form>
      </div>
      {Number(questionNumber) > 0 ? previousQuestion : null}
      {Number(questionNumber) !== 5 ? anyQuestion : finalQuestion}

      <Link to={`/`}>Exit</Link>
    </div>
  );
};

const mapStateToProps = (state) => ({
  auth: state.auth,
  omat: state.questions.omat,
  pmat: state.questions.pmat,
  cmat: state.questions.cmat,
});

export default connect(mapStateToProps)(Question);
 

Если я отключу функцию handleChange из onChange, переключатель будет отображаться правильно (проверено), при этом функция handleChange не будет изменена, значение после передачи снова вернется к нулю.

Я прикреплю журнал консоли, который может помочь в дальнейшем.

Журнал консоли Chrome

Вот изображение визуализированного переднего конца

Внешний интерфейс

Заранее спасибо!

Ответ №1:

Используйте shouldComponentUpdate метод жизненного цикла, чтобы предотвратить ненужную визуализацию, по умолчанию компонент повторно визуализируется при изменении состояния.

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

1. Я не смог найти реализацию в shouldComponentUpdate с помощью крючков, поэтому я прибегнул к react.memo, но, похоже, это не решило проблему с повторной визуализацией, с которой я сталкиваюсь.