我有一个简单的应用程序,显示当地酒店的列表。每个列表项都有一个<Link/>重定向到另一个组件的组件,该组件在地图上显示该特定酒店的位置。当切换路由时,组件似乎<ProductList/>被破坏了,其中的所有状态也被破坏了。所以每次当它进行新的 API 调用并重新渲染时。我尝试将其保存在本地存储中componentWillUnmount并检索它,useEffect()以便我可以有条件地进行 API 调用,它可以工作,但有时不起作用。
import React, { useState, useEffect} from "react";
import ProductItem from "../Components/ProductItem";
import axios from "axios";
const ProductList = () => {
const [hotelList, setHotelList] = useState([]);
// Get user location by IP
const getCurrentLocation = () => {
return fetch("https://ipinfo.io/json?token=MyToken").then(
(response) => response.json()
);
};
// Get list of hotels in specific location
const getHotelsInLocation = (destInfo) => {
console.log('destInfo is: ', destInfo)
const options = {
method: "GET",
url: "https://booking-com.p.rapidapi.com/v1/hotels/search",
params: {
checkout_date: "2022-10-01",
units: "metric",
dest_id: destInfo.destId,
dest_type: destInfo.destType,
locale: "en-gb",
adults_number: 2,
order_by: "popularity",
filter_by_currency: "USD",
checkin_date: "2022-09-30",
room_number: 1,
},
headers: {
"X-RapidAPI-Host": "booking-com.p.rapidapi.com",
"X-RapidAPI-Key": "MyApiKey",
},
};
axios
.request(options)
.then(function (response) {
console.log(response.data.result);
setHotelList(response.data.result);
})
.catch(function (error) {
console.error(error);
});
};
useEffect(() => {
getCurrentLocation().then((currentLocation) => {
console.log("Current city ", currentLocation.city);
const options = {
method: "GET",
url: "https://booking-com.p.rapidapi.com/v1/hotels/locations",
params: { locale: "en-gb", name: currentLocation.city },
headers: {
"X-RapidAPI-Host": "booking-com.p.rapidapi.com",
"X-RapidAPI-Key":
"MyApiKey",
},
};
axios
.request(options)
.then(function (response) {
console.log(response.data);
let destId = response.data[0].dest_id;
let destType = response.data[0].dest_type;
const destInfo = { destId, destType };
getHotelsInLocation(destInfo);
})
.catch(function (error) {
console.error(error);
});
});
}, []);
return (
<>
{hotelList.map((hotel) => (
<ProductItem key={hotel.hotel_id} hotel={hotel} />
))}
</>
);
};
export default ProductList;
Run Code Online (Sandbox Code Playgroud)
当我回到<ProductList/>组件时,我怎么能这样做,它不会发出新的 API 调用,而只是显示hotelList上一次调用的 API 调用。
在这种情况下,您需要将数据保存在集中存储中。为此,您有两个选择。一种是使用 context api,这是默认的 React 功能。另一种是使用 redux,它是单独的包。
我的意见是,你可以使用 context api。
下面给出了 context api 的一个简单示例,
文件上下文.jsx
import { createContext } from 'react'
export const Filecontext = createContext({});
Run Code Online (Sandbox Code Playgroud)
表单组件.jsx
import { Filecontext } from '../Contexts/Filecontext';
import { useContext } from 'react'
export default function Formcomponent() {
const { setName, setEmail, setMobileno, showAlert } = useContext(Filecontext)
return (
<>
<div className="form-group">
<label>Name : </label>
<input type="text" onChange={(e) => { setName(e.target.value) }} />
</div>
<div className="form-group">
<label>Email : </label>
<input type="email" onChange={(e) => { setEmail(e.target.value) }} />
</div>
<div className="form-group">
<label>Mobile No : </label>
<input type="number" onChange={(e) => { setMobileno(e.target.value) }} />
</div>
<div className="form-group">
<input type="submit" value="submit" onClick={() => { showAlert() }} />
</div>
</>
)
}
Run Code Online (Sandbox Code Playgroud)
列表组件.jsx
import { Filecontext } from '../Contexts/Filecontext';
import { useContext } from 'react'
export default function Listcomponent() {
const { name, email, mobileno } = useContext(Filecontext)
return (
<>
<p>Name :</p>{name}
<p>Email :</p>{email}
<p>Mobile No :</p>{mobileno}
</>
)
}
Run Code Online (Sandbox Code Playgroud)
应用程序.js
import logo from './logo.svg';
import './App.css';
import Formcomponent from './Components/Formcomponent';
import Listcomponent from './Components/Listcomponent';
import { Filecontext } from './Contexts/Filecontext';
import { useState } from 'react'
function App() {
const [name, setName] = useState("")
const [email, setEmail] = useState("")
const [mobileno, setMobileno] = useState("")
return (
<div className="App">
<Filecontext.Provider value={{ name, setName, email, setEmail, mobileno, setMobileno, showAlert }}>
<Formcomponent />
<Listcomponent />
</Filecontext.Provider>
</div>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
从上面的例子可以看出,Formcomponent可以在不同的路由中显示,也Listcomponent可以在不同的路由中显示。但即便如此,数据也可以在上下文的帮助下保留。
| 归档时间: |
|
| 查看次数: |
7957 次 |
| 最近记录: |