我一直在尝试了解如何使用异步数据填充我的模式而不导致父页面重新渲染。我尝试为模态创建一个单独的上下文,将模态移出父组件,但这样我仍然需要单击从父组件内部打开的模态。
卡片组件
import React, { useContext, useState, useRef, memo } from "react";
import { useNavigate } from "react-router-dom";
import { ShowProvider } from "../../ModalContext";
import { ShowContext } from "../../ModalContext";
import uniqid from "uniqid";
import { getText } from "../../helpers/getData";
import Modal from "../Modal/Modal";
import "./Card.css";
const customStyles = {
content: {
width: "70vw",
height: "60vh",
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
},
};
const Card = (props) => {
const navigate = useNavigate();
const { showData, setShowData } = useContext(ShowContext);
const img = props.book.book_image;
const title = props.book.title;
// get id then call for individual description
const getSummary = async (title) => {
const url = `https://www.googleapis.com/books/v1/volumes?q=${title}&key=${process.env.REACT_APP_GOOGLE_KEY}`;
const response = await getText(url);
const description = response.data.items[0].volumeInfo.description;
console.log(description);
setShowData({ description: description });
console.log(showData);
};
const open = () => {
console.log("open");
setShowData({ show: true });
getSummary(title);
};
const closed = () => {
console.log("close");
setShowData({ ...showData, show: false });
};
return (
<>
<main>
<Modal show={showData.show} handleClose={closed}>
<p> {showData.description}</p>
</Modal>
<button type="button" className="open" onClick={open}>
Description
</button>
<li className="card">
<img src={img} alt="book cover" key={uniqid()}></img>
</li>
</main>
</>
);
};
export default Card;
父组件
import React, { useEffect, useContext } from "react";
import { Context } from "../../../Context";
import "./Best.css";
import { getData } from "../../../helpers/getData";
import Card from "../.././Card/Card";
import Results from "../.././Results/Results";
import AnimatedLayout from "../../AnimatedLayout";
const Best = () => {
const { data, setData } = useContext(Context);
const getCurrent = async () => {
const url = `https://api.nytimes.com/svc/books/v3/lists/hardcover-fiction.json?api-key=XYZ&pages=1`;
const response = await getData(url);
if (response.message) {
console.log(response.message);
setData({ ...data, error: response.message });
alert(response.message);
}
console.log(response);
const newArr = data.results.slice();
const newData = [...newArr, ...response];
setData({ ...data, results: [...newData] });
};
useEffect(() => {
setData({ ...data, results: [] });
getCurrent();
}, []);
return (
<Results>
<AnimatedLayout>
<ul className="results-ul horizontal">
<li className="error fade">{data.error}</li>
{data.results.map((book) => {
return <Card book={book}>CARD</Card>;
})}
</ul>
</AnimatedLayout>
</Results>
);
};
export default Best;
我认为你只需要记住
Best
组件:export default React.memo(Best)
来自 React 文档
备忘录
memo 可让您在组件的 props 未更改时跳过重新渲染组件。