我正在创建一个简单的应用程序,它显示JSON文件中的用户卡列表及其在传单地图上的位置。
这部分已经完成,但现在我需要实现链接到每个用户的页面的功能,其中包含关于用户的更多信息以及他们在地图上的放大位置。
这是我的App.js文件:
import React from "react";
import { BrowserRouter as Router } from "react-router-dom";
import { Routes, Route } from "react-router-dom";
import UserList from "./pages/UserList";
import UserProfile from "./pages/UserProfile";
import "./App.css";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<UserList/>} />
<Route path="/pages/UserList" element={<UserList/>} />
<Route path="/pages/UserProfile" element={<UserProfile/>}/>
</Routes>
</Router>
);
}
export default App;
这是我的UserList页面,我在其中获取数据并将其列在用户卡和传单地图中,传单地图上有与每个用户位置相关的标记:
import { useState, useEffect } from "react";
import UserProvider, { useAppContext } from "../components/UserProvider";
import UserCard from "../components/UserCard";
import Markers from "../components/Markers";
import { MapContainer, TileLayer, useMap } from "react-leaflet";
import "../App.css";
function SetMapView() {
const { user } = useAppContext();
const map = useMap();
useEffect(() => {
if (!user) return;
const { lat, lng } = user.address.geo;
map.flyTo([lat, lng], 5);
}, [user]);
return null;
}
function UserList() {
const [users, setUsers] = useState([]);
const [data, setData] = useState([]);
useEffect(() => {
(async () => {
let userData;
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users/"
);
userData = await response.json();
} catch (error) {
console.log(error);
userData = [];
}
setUsers(userData);
setData(userData);
// Map
})();
}, []);
return (
<UserProvider>
<div className="App">
<div className="cards-container">
{users.map((user, index) => (
<UserCard userData={user} key={index} />
))}
</div>
<div className="map-container">
<MapContainer
center={[47.217324, 13.097555]}
zoom={0}
style={{ height: "100vh" }}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
<Markers data={data} />
<SetMapView />
</MapContainer>
</div>
</div>
</UserProvider>
);
}
export default UserList;
这是我的UserCar组件:
import './UserCard.css';
import { Link } from "react-router-dom";
const UserCard = ({ userData }) => {
return (
<Link to="./pages/UserProfile">
<div className="card">
<div className="card-name">{userData.name}</div>
<div className="card-body">
<div className="card-email"><i className="fa fa-envelope" /> {userData.email}</div>
<div className="card-phone"><i className="fa fa-phone" /> {userData.phone}</div>
<div className="card-website"><i className="fa fa-globe" /> {userData.website}</div>
<div className="card-company"><i className="fa fa-briefcase" /> {userData.company.name}</div>
</div>
</div>
</Link>
);
};
export default UserCard;
然后,当点击这些用户卡时,他们会看到包含完整用户信息及其在传单地图上放大位置的个人用户档案页面。
我已经有一个用户详细信息组件来显示用户信息的完整列表,这是代码:
const UserDetails = ({ userData }) => {
return (
<div className="card">
<div className="card-name">{userData.name}</div>
<div className="card-body">
<div className="card-username"><i className="fa fa-envelope" /> {userData.username}</div>
<div className="card-email"><i className="fa fa-envelope" /> {userData.email}</div>
<div className="card-address"><i className="fa fa-envelope" /> {userData.address.street}, {userData.address.suite}, {userData.address.city}, {userData.address.zipcode}, {userData.address.geo.lat}, {userData.address.geo.lng}</div>
<div className="card-phone"><i className="fa fa-phone" /> {userData.phone}</div>
<div className="card-website"><i className="fa fa-globe" /> {userData.website}</div>
<div className="card-company"><i className="fa fa-briefcase" /> {userData.company.name}, {userData.company.catchPhrase}, {userData.company.bs}</div>
</div>
</div>
);
};
export default UserDetails;
然后这是显示完整用户数据的页面:
import UserDetails from "../components/UserDetails";
function UserProfile({ userData }) {
return (
<UserDetails userData={userData} />
);
}
export default UserProfile;
这就是我陷入困境的地方。我不知道如何在这里提取、排序和显示特定的用户数据,这样这个页面就可以显示完整的用户数据和用户放大位置的地图。
如有任何帮助,我们将不胜感激。
您必须采用不同的方法来实现这一点。UserProvider
将不再帮助您。你需要做几个改变:
-
UserModal
不见了。你不需要它。 -
在导航到
UserProfile
路由时,单击用户详细信息以获取每个用户特定的数据时,您需要传递用户id。使用useParams可以获得id,然后获取特定的用户数据,然后用这些数据构建卡。现在,对于映射,您需要使映射成为一个单独的comp,其中您将有两个用例。一个渲染所有用户的所有标记。其次,使用单个用户数据只渲染一个标记。function UserProfile() { const { id } = useParams(); const { user } = useGetUser(id); const navigate = useNavigate(); const handleClick = () => { navigate("/"); }; return user && id ? ( <> <UserDetails userData={user} /> <Button onClick={handleClick}>Go back</Button> <Map user={user} /> </> ) : null; } function Map({ users, user }) { return ( <div className="map-container"> <MapContainer center={[47.217324, 13.097555]} zoom={0} style={{ height: "100vh" }} > <TileLayer url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' /> <Markers users={users} user={user} /> {user && <SetMapView user={user} />} </MapContainer> </div> ); }
我自定义了UserMarker
,创建了一个案例在所有标记上循环,另一个案例使用单个标记。还有更多。您可以查看演示