Refetch и Rerender компонента

Приветствую знатоков ReactJS! Написал вот такой компонент, по сути это модальное окно:

function ProviderCommentsDialog({ process }) {
  const steps = process.Steps.filter(step => step.parsedStepParams.isVisible);
  const processId = _.get(process, "id", "");

  const [open, setOpen] = useState(false);
  const [activeStep, setActiveStep] = useState(steps);
  const [comments, setComments] = useState([]);
  const [currentStepComments, setCurrentStepComments] = useState([]);

  const fetchAndSetComments = () => {
    fetchComments({ processId }).then(data => setComments(data));
  };

  const handleStep = step => () => {
    setActiveStep(step);
    setCurrentStepComments(
      comments.filter(comment => comment.stepId === steps[step].id)
    );
  };

  const formik = useFormik({
    initialValues: {
      text: "",
      stepId: "",
    },
    onSubmit: values => {
      createComment({
        processId,
        text: values.text,
        type: "Provider",
        stepId: steps[activeStep].id,
      });
      formik.resetForm();
    },
    validate: values => {
      const errors = {};

      if (!values.text) {
        errors.text = "Введите текст";
      }

      return errors;
    },
  });

  const handleSubmit = () => {
    formik.handleSubmit();
  };

  const handleClick = () => () => {
    setOpen(true);
    fetchAndSetComments();
  };

  const classes = useStyles();
  return (
    <div>
      <Button onClick={handleClick()} className={classes.mainButton}>
        Комментарии
      </Button>
      <Dialog open={open} fullWidth maxWidth="lg" keepMounted>
        <MuiDialogTitle disableTypography className={classes.root}>
          <Typography variant="h6">Комментарии Поставщика</Typography>
          <IconButton
            aria-label="close"
            className={classes.closeButton}
            onClick={() => setOpen(false)}
          >
            <CloseIcon />
          </IconButton>
        </MuiDialogTitle>
        <MuiDialogContent className={classes.root} dividers>
          <Comments
            currentStepComments={currentStepComments}
            activeStep={activeStep}
            handleSubmit={handleSubmit}
            handleStep={handleStep}
            steps={steps}
            formik={formik}
          />
        </MuiDialogContent>
        <Box display="flex" justifyContent="space-around" p={3} fullWidth>
          <Button
            autoFocus
            onClick={() => setOpen(false)}
            variant="contained"
            color="primary"
            size="lg"
          >
            Вердикт 1
          </Button>
          <Button
            autoFocus
            onClick={() => setOpen(false)}
            variant="contained"
            color="primary"
            size="lg"
          >
            Вердикт 2
          </Button>
        </Box>
      </Dialog>
    </div>
  );
}

Внутри него также есть компонент Comments

function Comments({
  currentStepComments,
  activeStep,
  handleStep,
  handleSubmit,
  steps,
  formik,
}) {
  const classes = useStyles();

  return (
    <div>
      <Stepper nonLinear activeStep={activeStep} orientation="vertical">
        {steps &&
          steps.map((el, index) => (
            <Step key={el.id}>
              <StepButton onClick={handleStep(index)}>
                {el.schema.name}
              </StepButton>
              <StepContent className={classes.modalContent}>
                {currentStepComments &&
                  currentStepComments.map(comment => (
                    <Box className={classes.commentBox}>
                      <Box className={classes.commentHeader}>
                        <Box component="span" className={classes.commentAuthor}>
                          {comment.authorId}
                        </Box>
                        <Box component="span" className={classes.commentDate}>
                          {new Date(comment.creationDate).toLocaleString("ru", {
                            year: "numeric",
                            month: "numeric",
                            day: "numeric",
                          })}
                        </Box>
                      </Box>
                      <Box component="span" className={classes.commentText}>
                        {comment.text}
                      </Box>
                    </Box>
                  ))}
                <form onSubmit={formik.handleSubmit}>
                  <Box className={classes.sendCommentBox}>
                    <TextField
                      id="text"
                      label="Комментарий"
                      variant="filled"
                      fullWidth
                      multiline
                      value={formik.values.text}
                      error={formik.touched.text && !!formik.errors.text}
                      helperText={formik.touched.text && formik.errors.text}
                      onChange={formik.handleChange}
                    />
                    <Button
                      className={classes.sendCommentButton}
                      variant="contained"
                      size="large"
                      color="primary"
                      onClick={handleSubmit}
                    >
                      Отправить
                    </Button>
                  </Box>
                </form>
              </StepContent>
            </Step>
          ))}
      </Stepper>
    </div>
  );
}

Столкнулся со следующей проблемой, при отправке комментария, то есть нажатии кнопку "Отправить", мне нужно сделать refetch запроса комментариев и сделать ре-рендер компонента с фильтрацией как в setCurrentStepComments(), чтобы комментарий сразу отобразился в списке, пока дошёл до решения когда кнопу "Отправить" нужно нажимать два раза для ре-рендера (не добавлял сюда данное решение). Запрос для фетча данных fetchAndSetComments(). Как лучше реализовать данную задачу, заранее благодарю за ваши ответы! P.S. Также приветствуется рекомендации по оптимизации кода :)


Ответы (0 шт):