我正在使用反应钩子,我有一个子组件Addmember
和一个父组件MemberList
。在成员列表中,用户单击添加成员并弹出一个模型(子组件(,然后用户可以输入一些表单数据,然后提交表单。然后,窗体将新成员添加到 MongoDB 集合中。.then()
它调用parentCallback(true)
将loading
的父状态翻转为true
,然后触发组件重新渲染。这是成功的工作。
我无法解决这个问题的问题是,当父级到达数据库以getMembers
它不返回新添加的成员时,它重新渲染。如果我刷新页面,相同的调用将成功抓住所有成员,包括最近添加的成员。
会员名单.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 = () => {
const [family, setFamily] = useState({});
const [familyMembersList, setFamilyMembersList] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (loading) {
fetchData();
}
}, [loading]);
async function fetchData() {
getFamily.then(result => {
console.log('get family');
setFamily(result);
});
getMembers.then(result => {
try {
console.log('set family list');
console.log(result);
setFamilyMembersList(
result.map((child, index) => (
<Member
key={index}
index={child._id}
balance={child.balance}
firstName={child.firstName}
lastName={child.lastName}
birthday={child.birthday}
role={child.role[0]}
/>
))
);
} 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 (
<div className="ibox">
<div className="ibox-title">
<h5>{family.name}</h5>
<div className="ibox-tools">
<span className="label label-warning-light float-right">
{familyMembersList.length} Member(s)
</span>
</div>
</div>
<div className="ibox-content">
<div className="feed-activity-list">
{loading ? (
<Spinner animation="grow" role="status" variant="dark">
<span className="sr-only">Loading...</span>
</Spinner>
) : (
familyMembersList
)}
</div>
<div className="d-flex">
<a
className="btn btn-primary text-white m-t"
data-toggle="modal"
data-target={"#newMemberModel"}
>
<i className="fa fa-plus"></i> New Member
</a>
<a
className="btn btn-danger text-white m-t m-l"
data-toggle="modal"
data-target={"#removeMemberModel"}
>
<i className="fa fa-minus"></i> Remove Member
</a>
</div>
</div>
{/* Add Member Model */}
<AddMemberModal parentCallback={handleCallback}/>
{/* Remove Member Model */}
<RemoveMemberModel />
</div>
);
};
export default MemberList;
添加成员.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}) => {
const [date, setDate] = useState(new Date());
const { handleSubmit, register, errors } = useForm();
// const handleDateChange = date => {
// setDate(date)
// }
const onSubmit = (data) => {
try {
data.familyId = "5dddf14df965552b3da57be1";
postMember(data).then(async () => 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 (
<div
className="modal inmodal"
id={"newMemberModel"}
tabIndex="-1"
role="dialog"
style={{ display: "none" }}
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content animated fadeIn">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span className="sr-only">Close</span>
</button>
<h4 className="modal-title">New Family Member</h4>
</div>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="modal-body">
<div className="row">
<div className="col">
<div className="form-group">
<label>First Name</label>
<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"
}
})}
/>
<div className="text-danger">
{errors.firstName && errors.firstName.message}
</div>
</div>
<div className="form-group">
<label className="font-normal">Birthday</label>
<div className="input-group date">
{/* <DatePicker
selected={date}
onChange={handleDateChange}
placeholderText="Click to select a date"
isClearable
peekNextMonth
showMonthDropdown
showYearDropdown
dropdownMode="select"
ref={e =>register({
name: "Birthday",
required: false
})}
/> */}
<input
type="text"
placeholder="01/01/01"
className="form-control"
name="birthDate"
ref={register({
required: false
})}
/>
</div>
</div>
</div>
<div className="col">
<div className="form-group">
<label>Last Name</label>
<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"
}
})}
/>
<div className="text-danger">
{errors.lastName && errors.lastName.message}
</div>
</div>
<div className="form-group">
<label>Role</label>
<select
className="custom-select"
name="role"
ref={register({ required: true })}
>
<option defaultValue>Select Role</option>
<option value="Adult">Adult</option>
<option value="Child">Child</option>
</select>
</div>
</div>
</div>
</div>
<div className="modal-footer">
<button
type="button"
className="btn btn-white"
data-dismiss="modal"
>
Close
</button>
<button type="submit" className="btn btn-primary">
Add Member
</button>
</div>
</form>
</div>
</div>
</div>
);
};
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];
let newMember = (
<Member
key={data._id}
index={data._id}
balance={0}
firstName={data.firstName}
lastName={data.lastName}
birthday={data.birthday}
role={data.role}
/>
)
arr.push(newMember);
console.log(arr);
setFamilyMembersList(arr);
setLoading(false);
}
并在您的AddMember.js
onSubmit
方法更改为:
const onSubmit = (data) => {
try {
data.familyId = "5dddf14df965552b3da57be1";
postMember(data).then(async () => parentCallback(data));
} catch (error) {
...
}
};