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. Также приветствуется рекомендации по оптимизации кода :)