Я использую перехватчики реагирования, и у меня есть дочерний компонент Addmember и родительский компонент MemberList . В списке членов пользователь нажимает добавить члена, и появляется всплывающая модель (дочерний компонент), а затем пользователь может ввести некоторые данные формы, а затем отправить форму. Затем форма добавляет нового члена в коллекцию MongoDB. .then() он вызвал parentCallback(true) чтобы перевернуть родительское состояние loading в true что вызовет повторную визуализацию компонента. Который успешно работает.

Проблема, с которой я не могу разобраться, заключается в том, что при повторном рендеринге родителя, когда он попадает в базу данных, getMembers не возвращает вновь добавленного члена. Если я обновлю страницу, тот же вызов успешно захватит всех участников, включая недавнее добавление.

MemberList.js:

 import React, { useState, useEffect } from "react"; import Spinner from "react-bootstrap/Spinner"; import { toast } from "react-toastify"; import { css } from "glamor"; import "react-toastify/dist/ReactToastify.css"; import "react-datepicker/dist/react-datepicker.css"; import "../Styles/ReactDatePicker.css"; import Member from "./Member"; import AddMemberModal from "../models/AddMember"; import RemoveMemberModel from "../models/RemoveMember"; const { getFamily, getMembers } = require("../Utils/Service"); const MemberList = () ={amp}gt; { const [family, setFamily] = useState({}); const [familyMembersList, setFamilyMembersList] = useState([]); const [loading, setLoading] = useState(true); useEffect(() ={amp}gt; { if (loading) { fetchData(); } }, [loading]); async function fetchData() { getFamily.then(result ={amp}gt; { console.log('get family'); setFamily(result); }); getMembers.then(result ={amp}gt; { try { console.log('set family list'); console.log(result); setFamilyMembersList( result.map((child, index) ={amp}gt; ( {amp}lt;Member key={index} index={child._id} balance={child.balance} firstName={child.firstName} lastName={child.lastName} birthday={child.birthday} role={child.role[0]} /{amp}gt; )) ); } catch (e) { toast.error("500: Error with Service Call", { position: "top-right", autoClose: 5000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, className: css({ background: "#ed5565 !important" }) }); } finally { setLoading(false); } }); } function handleCallback() { setLoading(true); } return ( {amp}lt;div className="ibox"{amp}gt; {amp}lt;div className="ibox-title"{amp}gt; {amp}lt;h5{amp}gt;{family.name}{amp}lt;/h5{amp}gt; {amp}lt;div className="ibox-tools"{amp}gt; {amp}lt;span className="label label-warning-light float-right"{amp}gt; {familyMembersList.length} Member(s) {amp}lt;/span{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;div className="ibox-content"{amp}gt; {amp}lt;div className="feed-activity-list"{amp}gt; {loading ? ( {amp}lt;Spinner animation="grow" role="status" variant="dark"{amp}gt; {amp}lt;span className="sr-only"{amp}gt;Loading...{amp}lt;/span{amp}gt; {amp}lt;/Spinner{amp}gt; ) : ( familyMembersList )} {amp}lt;/div{amp}gt; {amp}lt;div className="d-flex"{amp}gt; {amp}lt;a className="btn btn-primary text-white mt" data-toggle="modal" data-target={"#newMemberModel"} {amp}gt; {amp}lt;i className="fa fa-plus"{amp}gt;{amp}lt;/i{amp}gt; New Member {amp}lt;/a{amp}gt; {amp}lt;a className="btn btn-danger text-white mt ml" data-toggle="modal" data-target={"#removeMemberModel"} {amp}gt; {amp}lt;i className="fa fa-minus"{amp}gt;{amp}lt;/i{amp}gt; Remove Member {amp}lt;/a{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {/* Add Member Model */} {amp}lt;AddMemberModal parentCallback={handleCallback}/{amp}gt; {/* Remove Member Model */} {amp}lt;RemoveMemberModel /{amp}gt; {amp}lt;/div{amp}gt; ); }; export default MemberList; 

AddMember.js

 import React, { useState, useEffect } from "react"; import { toast } from "react-toastify"; import DatePicker from "react-datepicker"; import useForm from "react-hook-form"; import { css } from "glamor"; import "react-toastify/dist/ReactToastify.css"; import "react-datepicker/dist/react-datepicker.css"; import "../Styles/ReactDatePicker.css"; const { postMember } = require("../Utils/Service"); const AddMemberModal = ({parentCallback}) ={amp}gt; { const [date, setDate] = useState(new Date()); const { handleSubmit, register, errors } = useForm(); // const handleDateChange = date ={amp}gt; { // setDate(date) // } const onSubmit = (data) ={amp}gt; { try { data.familyId = "5dddf14df965552b3da57be1"; postMember(data).then(async () ={amp}gt; parentCallback(true)); } catch (error) { toast.error("500: Error with Service Call", { position: "top-right", autoClose: 5000, hideProgressBar: false, closeOnClick: true, pauseOnHover: true, draggable: true, className: css({ background: "#ed5565 !important" }) }); } }; return ( {amp}lt;div className="modal inmodal" id={"newMemberModel"} tabIndex="-1" role="dialog" style={{ display: "none" }} aria-hidden="true" {amp}gt; {amp}lt;div className="modal-dialog"{amp}gt; {amp}lt;div className="modal-content animated fadeIn"{amp}gt; {amp}lt;div className="modal-header"{amp}gt; {amp}lt;button type="button" className="close" data-dismiss="modal"{amp}gt; {amp}lt;span aria-hidden="true"{amp}gt;×{amp}lt;/span{amp}gt; {amp}lt;span className="sr-only"{amp}gt;Close{amp}lt;/span{amp}gt; {amp}lt;/button{amp}gt; {amp}lt;h4 className="modal-title"{amp}gt;New Family Member{amp}lt;/h4{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;form onSubmit={handleSubmit(onSubmit)}{amp}gt; {amp}lt;div className="modal-body"{amp}gt; {amp}lt;div className="row"{amp}gt; {amp}lt;div className="col"{amp}gt; {amp}lt;div className="form-group"{amp}gt; {amp}lt;label{amp}gt;First Name{amp}lt;/label{amp}gt; {amp}lt;input type="text" placeholder="First Name" className="form-control" name="firstName" ref={register({ required: true, pattern: { value: /^[a-zA-Z] $/i, message: "Invalid First Name" } })} /{amp}gt; {amp}lt;div className="text-danger"{amp}gt; {errors.firstName {amp}amp;{amp}amp; errors.firstName.message} {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;div className="form-group"{amp}gt; {amp}lt;label className="font-normal"{amp}gt;Birthday{amp}lt;/label{amp}gt; {amp}lt;div className="input-group date"{amp}gt; {/* {amp}lt;DatePicker selected={date} onChange={handleDateChange} placeholderText="Click to select a date" isClearable peekNextMonth showMonthDropdown showYearDropdown dropdownMode="select" ref={e ={amp}gt;register({ name: "Birthday", required: false })} /{amp}gt; */} {amp}lt;input type="text" placeholder="01/01/01" className="form-control" name="birthDate" ref={register({ required: false })} /{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;div className="col"{amp}gt; {amp}lt;div className="form-group"{amp}gt; {amp}lt;label{amp}gt;Last Name{amp}lt;/label{amp}gt; {amp}lt;input type="text" placeholder="Last Name" className="form-control" name="lastName" ref={register({ required: true, pattern: { value: /^[a-zA-Z] $/i, message: "Invalid Last Name" } })} /{amp}gt; {amp}lt;div className="text-danger"{amp}gt; {errors.lastName {amp}amp;{amp}amp; errors.lastName.message} {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;div className="form-group"{amp}gt; {amp}lt;label{amp}gt;Role{amp}lt;/label{amp}gt; {amp}lt;select className="custom-select" name="role" ref={register({ required: true })} {amp}gt; {amp}lt;option defaultValue{amp}gt;Select Role{amp}lt;/option{amp}gt; {amp}lt;option value="Adult"{amp}gt;Adult{amp}lt;/option{amp}gt; {amp}lt;option value="Child"{amp}gt;Child{amp}lt;/option{amp}gt; {amp}lt;/select{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;div className="modal-footer"{amp}gt; {amp}lt;button type="button" className="btn btn-white" data-dismiss="modal" {amp}gt; Close {amp}lt;/button{amp}gt; {amp}lt;button type="submit" className="btn btn-primary"{amp}gt; Add Member {amp}lt;/button{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/form{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; {amp}lt;/div{amp}gt; ); }; export default AddMemberModal; 

Порядок, в котором я могу видеть на консоли происходящее:

 [Log] get family [Log] set family list [Log] [Object, Object, Object, Object, Object, Object, Object, Object, Object, Object] (10) 

В объекте, в котором он возвращается, отсутствует последнее добавление члена. Я попытался добавить тайм-ауты, думая, что это может быть проблема синхронизации, но это не изменило эту проблему.

Вы можете добавить отправленные данные в массив вместо обновления страницы

в файле MemberList.js измените свой handleCallback на это:

 function handleCallback(data){ const arr = [...familyMembersList]; arr.push(data); setFamilyMembersList(arr); setLoading(false); } 

и в вашем AddMember.js измените метод onSubmit на этот:

 const onSubmit = (data) ={amp}gt; { try { data.familyId = "5dddf14df965552b3da57be1"; postMember(data).then(async () ={amp}gt; parentCallback(data)); } catch (error) { ... } }; 

Посмотрите на эту статью Асинхронные потоки с React . Короче говоря, решение заключается в использовании useEffect .