我有一個這個組件,我在其中從 API 獲取資料并將其顯示在螢屏上:
const RestaurantsList = () => {
const [restaurants, setRestaurants] = useState([]);
useEffect(() => {
const fetchData = async () => {
const response = await fetch("http://localhost:3001/api/v1/restaurants");
const data = await response.json();
//console.log(data);
setRestaurants(data);
};
fetchData();
}, []);
...
我有另一個組件 AddRestaurant,我在其中向 API 發出 Post 請求以添加新餐廳:
const AddRestaurant = () => {
const [name, setName] = useState("");
const [location, setLocation] = useState("");
const [priceRange, setPriceRange] = useState("");
function nameUpdate(e) {
setName(e.target.value);
}
function locationUpdate(e) {
setLocation(e.target.value);
}
const handleSubmit = async function (e) {
//e.preventDefault();
try {
await fetch("http://localhost:3001/api/v1/restaurants", {
method: "POST",
made: "cors",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name,
location,
price_range: priceRange,
}),
});
} catch (err) {
console.log(err);
}
setName("");
setLocation("");
setPriceRange("");
};
...
問題是,當我添加一個新餐廳時,我想在不重繪 頁面的情況下添加串列。如果我在 useEffect 上添加 [restaurants] 依賴項,它會不斷在回圈中發出 GET 請求。
兩個組件都是這個組件的子組件:
const Home = () => {
return (
<div>
<Header />
<AddRestaurant />
<RestaurantsList />
</div>
);
};
export default Home;
最好的解決方案是什么?
更新
它適用于安德烈的解決方案,但現在我想在洗掉餐廳時也這樣做。我應用了相同的方法,但這不起作用:
<button
className="btn btn-danger"
onClick={(e) => onDelete(res.id, e)}
>
Delete
</button>
const onDelete = async (id, e) => {
e.preventDefault();
try {
await fetch(`http://localhost:3001/api/v1/restaurants/${id}`, {
method: "DELETE",
});
} catch (err) {
console.log(err);
}
setFetchRestaurants(true);
};
onDelete 按鈕和函式位于 RestaurantList 組件上。
uj5u.com熱心網友回復:
一種解決方案是添加一個頂級狀態,該狀態開始true并獲取初始資料。我們將其設定為false 資料獲取完成時。
const Home = () => {
const [fetchRestaurants, setFetchRestaurants] = useState(true)
return (
<div>
<Header />
<AddRestaurant setFetchRestaurants={setFetchRestaurants} />
<RestaurantsList fetchRestaurants={fetchRestaurants} setFetchRestaurants={setFetchRestaurants} />
</div>
)
}
export default Home
const RestaurantsList = ({ fetchRestaurants, setFetchRestaurants }) => {
const [restaurants, setRestaurants] = useState([])
useEffect(() => {
if (fetchRestaurants) {
const fetchData = async () => {
const response = await fetch('http://localhost:3001/api/v1/restaurants')
const data = await response.json()
// console.log(data);
setRestaurants(data)
}
fetchData()
setFetchRestaurants(false)
}
}, [fetchRestaurants, setFetchRestaurants])
// ...
}
然后在AddRestaurant:
const handleSubmit = async function (e) {
// ...
setFetchRestaurants(true)
setName('')
setLocation('')
setPriceRange('')
}
當fetchRestaurants更改時,RestaurantsList 將重新渲染并獲取新資料。
RTK Query是一個可以為您完成大量作業的庫,請查看此處的檔案:
- https://redux-toolkit.js.org/rtk-query/overview
- https://redux-toolkit.js.org/rtk-query/usage/automated-refetching
uj5u.com熱心網友回復:
我們應該使用一個變數來通知組件有新的更新。
我會建議做這樣的事情。
export default function Home () {
const [
timeOfLastRestaurantCreation,
setTimeOfLastRestaurantCreation
] = useState<string>()
return (
<div>
<Header />
<AddRestaurant
onAddRestaurant={() => {
setTimeOfLastRestaurantCreation(new Date().toISOString())
}}
/>
<RestaurantsList
timeOfLastRestaurantCreation={timeOfLastRestaurantCreation}
/>
</div>
)
}
附注。為什么是 ISOString 而不是 Date?更容易除錯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383868.html
