javascript - 渲染从父组件传递到模态子组件的数据反应
问题描述
我有一个从我的 API 获得的对象数组,然后将它们作为表行显示给父组件,如下所示:
每行都有自己的编辑按钮,当我单击时,它将弹出一个模式(不重定向到另一个页面),它将包含一些基于我单击的行的信息。下面是当我单击以“Mamang Racing”作为客户端名称的第四行时的示例。
reviewDetailModal .js
问题是,在子组件(模态组件)上,当我出于某种原因要编辑任何其他行时,它仍会向我显示最新数据(在本例中为第四行)。
代码如下所示:
审查.js
const Review = () => {
const [showModal, setShowModal] = useState("close");
const [review, setReview] = useState([]);
const handleClose = () => setShowModal("close");
const handleShowModalOne = () => setShowModal("modal-one");
const handleShowModalTwo = () => setShowModal("modal-two");
useEffect(() => {
let isMounted = false;
const FetchReview = async () => {
await publicAxios
.get("/api/review/")
.then((result) => {
setReview(result.data);
})
.catch((err) => console.log(err));
};
FetchReview();
console.log(review);
return () => {
isMounted = true;
};
}, []);
return (
<Layout>
<Container fluid style={{ overflowY: "auto", paddingTop: "10px" }}>
<div className="d-flex flex-row-reverse">
<Button
variant="success"
className="mb-2"
onClick={handleShowModalOne}
>
<FaPlusCircle /> Add Testimonial
</Button>
<AddReviewModal isShow={showModal} isClose={handleClose} />
</div>
<Table striped bordered hover className="text-center">
<thead>
<tr>
<th>Client</th>
<th>Review</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{review.map((item) => (
<tr key={item._id}>
<td className="align-middle">{item.clientName}</td>
<td className="align-middle">{item.projectName} </td>
<td style={{ width: "200px" }} className="align-middle">
<Button variant="primary" className="m-1 ">
<FaEye />
</Button>
<Button
variant="warning"
className="m-1"
onClick={handleShowModalTwo}
>
<FaPenSquare />
</Button>
<ReviewDetailModal
data={item}
isShow={showModal}
isClose={handleClose}
/>
<Button variant="danger" className="m-1">
<FaTrashAlt />
</Button>
</td>
</tr>
))}
</tbody>
</Table>
</Container>
</Layout>
);
};
reviewDetailModal.js
const ReviewDetailModal = ({ data, isShow, isClose }) => {
return (
<Modal show={isShow === "modal-two"} onHide={isClose}>
<Modal.Header>
<Modal.Title>Edit Review</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group controlId="form.InputName">
<Form.Label>Your Name</Form.Label>
<Form.Control
type="text"
placeholder="Nama Anda"
defaultValue={data.clientName}
/>
</Form.Group>
<Form.Group controlId="form.InputName">
<Form.Label>Project Name</Form.Label>
<Form.Control
type="text"
placeholder="Nama Anda"
defaultValue={data.projectName}
/>
</Form.Group>
<Form.Group controlId="form.Rating">
<Form.Label>Tinggalkan Rating : </Form.Label>
<Form.Control as="select" defaultValue={data.rating}>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Form.Control>
</Form.Group>
<Form.Group controlId="form.TextArea">
<Form.Label>Kalimat Review</Form.Label>
<Form.Control
as="textarea"
rows={3}
defaultValue={data.description}
/>
</Form.Group>
<Form.Group>
<label>Foto Anda</label>
<Form.File id="pictureFile" />
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button onClick={isClose}>Close</Button>
</Modal.Footer>
</Modal>
);
};
API 结果,我的数据之一:
Array(4) [ {…}, {…}, {…}, {…} ]
0: Object { _id: "60c18f1de4579e22d0e636cb", clientName: "pak dwek", projectName: "Landing Page Pakdwek", … }
__v: 0
_id: "60c18f1de4579e22d0e636cb"
clientName: "pak dwek"
createdAt: "2021-06-10T04:03:41.594Z"
description: "Sangat Baik , pelayanan memuaskan"
photo: "img/pakdhe.jpg"
projectName: "Landing Page Pakdwek"
score: 5
updatedAt: "2021-06-10T04:03:41.594Z"
<prototype>: Object { … }
1: Object { _id: "60c34afac1bdda333840a1cb", clientName: "alex", projectName: "landing page alex", … }
__v: 0
_id: "60c34afac1bdda333840a1cb"
clientName: "alex"
createdAt: "2021-06-11T11:37:30.852Z"
description: "sangat baik"
photo: "https://res.cloudinary.com/rembux-developer/image/upload/v1623411449/review-photos/ipbqv8xxqfs45yx9s5kz.jpg"
projectName: "landing page alex"
rating: 4
updatedAt: "2021-06-11T11:37:30.852Z"
<prototype>: Object { … }
2: Object { _id: "60c34b7ec1bdda333840a1cc", clientName: "Suhardono", projectName: "Project Web APp", … }
__v: 0
_id: "60c34b7ec1bdda333840a1cc"
clientName: "Suhardono"
createdAt: "2021-06-11T11:39:42.456Z"
description: "buruk"
photo: "https://res.cloudinary.com/rembux-developer/image/upload/v1623411581/review-photos/hkxt98hm28sb6sgc3wao.jpg"
projectName: "Project Web APp"
rating: 2
updatedAt: "2021-06-11T11:39:42.456Z"
<prototype>: Object { … }
3: Object { _id: "60c6d7a5eca83317bc8d0c5c", clientName: "Mamang Racing", projectName: "Test Project", … }
__v: 0
_id: "60c6d7a5eca83317bc8d0c5c"
clientName: "Mamang Racing"
createdAt: "2021-06-14T04:14:29.910Z"
description: "Bagusssss"
photo: "https://res.cloudinary.com/rembux-developer/image/upload/v1623644068/review-photos/sdha9mu1r6a3jvjfbqpm.png"
projectName: "Test Project"
rating: 3
updatedAt: "2021-06-14T04:14:29.910Z"
<prototype>: Object { … }
length: 4
解决方案
您必须创建一个保存方法并通过该保存方法将模态数据传递给Review 组件。
评论.js
const Review = () => {
const [showModal, setShowModal] = useState("close");
const [review, setReview] = useState([]);
const handleClose = () => setShowModal("close");
const handleShowModalOne = () => setShowModal("modal-one");
const handleShowModalTwo = () => setShowModal("modal-two");
useEffect(() => {
let isMounted = false;
const FetchReview = async () => {
await publicAxios
.get("/api/review/")
.then((result) => {
setReview(result.data);
})
.catch((err) => console.log(err));
};
FetchReview();
console.log(review);
return () => {
isMounted = true;
};
}, []);
const onChangeReview = (index, obj) => {
setReview((prev) =>
prev.map((item, i) => (i === index ? { ...item, ...obj } : item))
);
}; // Update the state using the modal submitted data
return (
<Layout>
<Container fluid style={{ overflowY: "auto", paddingTop: "10px" }}>
<div className="d-flex flex-row-reverse">
<Button
variant="success"
className="mb-2"
onClick={handleShowModalOne}
>
<FaPlusCircle /> Add Testimonial
</Button>
<AddReviewModal isShow={showModal} isClose={handleClose} />
</div>
<Table striped bordered hover className="text-center">
<thead>
<tr>
<th>Client</th>
<th>Review</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{review.map((item, index) => (
<tr key={item._id}>
<td className="align-middle">{item.clientName}</td>
<td className="align-middle">{item.projectName} </td>
<td style={{ width: "200px" }} className="align-middle">
<Button variant="primary" className="m-1 ">
<FaEye />
</Button>
<Button
variant="warning"
className="m-1"
onClick={handleShowModalTwo}
>
<FaPenSquare />
</Button>
<ReviewDetailModal
index={index} {/* Pass the index of the item */}
data={item}
isShow={showModal}
isClose={handleClose}
onChangeReview={onChangeReview} {/* Pass the handler as an prop */}
/>
<Button variant="danger" className="m-1">
<FaTrashAlt />
</Button>
</td>
</tr>
))}
</tbody>
</Table>
</Container>
</Layout>
);
};
reviewDetailModal.js
const ReviewDetailModal = ({
index,
data,
isShow,
isClose,
onChangeReview
}) => {
const name = useRef(null);
const project = useRef(null);
const rate = useRef(null);
const review = useRef(null);
const picture = useRef(null); // Creating references to Modal form fields
const onSave = () => {
onChangeReview(index, {
clientName: name.current.value,
projectName: project.current.value,
score: rate.current.value,
review: review.current.value, // review info not exist in API returned array
photo: picture.current.value
});
}; // Model data save handler
return (
<Modal show={isShow === "modal-two"} onHide={isClose}>
<Modal.Header>
<Modal.Title>Edit Review</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group controlId="form.InputName">
<Form.Label>Your Name</Form.Label>
<Form.Control
type="text"
placeholder="Nama Anda"
defaultValue={data.clientName}
ref={name} {/* Pass the references to the the form fields */}
/>
</Form.Group>
<Form.Group controlId="form.InputName">
<Form.Label>Project Name</Form.Label>
<Form.Control
type="text"
placeholder="Nama Anda"
defaultValue={data.projectName}
ref={project}
/>
</Form.Group>
<Form.Group controlId="form.Rating">
<Form.Label>Tinggalkan Rating : </Form.Label>
<Form.Control as="select" defaultValue={data.rating} ref={rate}>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Form.Control>
</Form.Group>
<Form.Group controlId="form.TextArea">
<Form.Label>Kalimat Review</Form.Label>
<Form.Control
as="textarea"
rows={3}
defaultValue={data.description}
ref={review}
/>
</Form.Group>
<Form.Group>
<label>Foto Anda</label>
<Form.File id="pictureFile" ref={picture} />
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button onClick={onSave}>Save</Button>{" "}
{/* Add the Save handler to onClick */}
<Button onClick={isClose}>Close</Button>
</Modal.Footer>
</Modal>
);
};
如果您需要进一步的支持,请告诉我。
推荐阅读
- java - 如何更新 Maven 版本?
- python - 有没有更好的方法来检查输入中的字符串?
- php - PHP 到 MSSQL 的连接失败,因为我的 MSSQL 密码中包含 $ 特殊字符
- r - 在 R 闪亮中,如何指定用于绘图的反应对象列?
- charts - 如何根据每个窗格的平均值在 Tableau 中为条形图着色?
- vba - 向集合 VB 添加第二个对象
- javascript - charAt 不适用于在 javascript 中动态创建的元素
- c# - 列出命令需要 allowAdmin 用于 redis
- c# - C# 从队列中选择一个随机项
- plotly - 如何在绘图中显示来自 GeoJSON 的多边形?