[英]Custom React component(react-hook) not re-rendering
I have a component that fetches data from my mongoDB it then renders a list of child components.我有一个组件从我的 mongoDB 中获取数据,然后呈现一个子组件列表。 It the "list" component I have a post that adds a new member to the database.
它是“列表”组件,我有一篇将新成员添加到数据库的帖子。 Upon addition im trying to get the list to re-fetch the data and re-render the list component.
此外,我试图获取列表以重新获取数据并重新呈现列表组件。
List Component:列表组件:
import React, { useState, useEffect } from "react";
import axios from "axios";
import Spinner from "react-bootstrap/Spinner";
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";
import Member from "./Member";
const { getFamily, getMembers, postMember } = require("../Utils/Service");
const MemberList = () => {
const [family, setFamily] = useState({});
const [familyMembers, setFamilyMembers] = useState([]);
const [loading, setLoading] = useState(true);
const [date, setDate] = useState(new Date());
const { handleSubmit, register, errors } = useForm();
async function fetchData() {
getFamily.then(result => {
setFamily(result);
});
getMembers.then(result => {
try {
setFamilyMembers(
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);
}
});
}
useEffect(() => {
if (loading) {
fetchData();
}
}, [loading]);
// const handleDateChange = date => {
// setDate(date)
// }
const onSubmit = data => {
data.familyId = "5dddf14df965552b3da57be1";
postMember(data).then(
????????????
);
};
return (
<div className="ibox">
<div className="ibox-title">
<h5>{family.name}</h5>
<div className="ibox-tools">
<span className="label label-warning-light float-right">
{familyMembers.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>
) : (
familyMembers
)}
</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>
{/* New Member Model */}
<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>
{/* Remove Member Model */}
<div
className="modal inmodal"
id={"removeMemberModel"}
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">Remove Family Member</h4>
</div>
<div className="modal-body"></div>
<div className="modal-footer">
<button
type="button"
className="btn btn-white"
data-dismiss="modal"
>
Close
</button>
<button type="button" className="btn btn-danger">
Remove Member
</button>
</div>
</div>
</div>
</div>
</div>
);
};
export default MemberList;
within the code in the onSubmit
function with posts the data inside the .then
is where im trying to re-render the entire component and/or fetch the data agin.在代码内
onSubmit
与职位功能内部的数据.then
是其中即时试图重新渲染整个组分和/或获取数据AGIN。
right now, your useEffect
is only dependent on the property loading
, if you change the property then the effect will run again.现在,您的
useEffect
仅依赖于属性loading
,如果您更改属性,则效果将再次运行。
https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect
In your component, you can call this.forceUpdate() to force a rerender.在您的组件中,您可以调用 this.forceUpdate() 来强制重新渲染。
I think you can also call your fetchData function again inside your .then() block, if you make the callback inside the .then() an async function.我认为您也可以在 .then() 块中再次调用 fetchData 函数,如果您将 .then() 中的回调设为异步函数。
postMember(data).then( async () => this.fetchData() ); postMember(data).then( async () => this.fetchData() );
or或者
postMember(data).then( () => this.forceUpdate() ); postMember(data).then(() => this.forceUpdate());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.