使用两个useEffect,但组件只在执行第一个后返回



在渲染中(在Rides组件的return()中),ride。距离是未定义的,但在第二次使用效果在地图函数内打印每个骑他们有骑。距离一些未定义的值

组件渲染后执行第一个useEffect和第二个useEffect运行后或有一些其他问题?

如何在渲染第二个useEffect完成执行之前实现这一点?

import Navbar from "./Navbar";
const Rides = () => {
const [rides, setRides] = useState([]);
const [user, setUser] = useState({});
const [updatedRides, setUpdatedRides] = useState([]);

useEffect(() => {
const fetchRides = async () => {
const data = await fetch('https://assessment.api.vweb.app/rides');
const json = await data.json();
setRides(json);
console.log(json);
}
const fetchUser = async () => {
const data = await fetch('https://assessment.api.vweb.app/user');
const json = await data.json();
console.log(json);
setUser(json);
}

const makeNetworkCalls = async() => {
await fetchRides();
await fetchUser();
}
makeNetworkCalls().catch((e) => {
console.log(e);
})
}, [])
useEffect(() => {
const calculateDistance = async(path, user_station) => {
let min = Math.abs(user_station - path[0]);
for(let i = 0; i<path.length; i++){
if(path[i] === user_station){
return 0;
}
if(Math.abs(path[i] - user_station) < min){
min = Math.abs(path[i] - user_station);
}
}
return min;
}
const updaterides = async() => {
setUpdatedRides(rides);
updatedRides.map(async(ride) => {
ride.distance = await calculateDistance(ride.station_path, user.station_code);
console.log(ride);
})
}
updaterides().catch((e) => {
console.log(e);
})
}, [rides]);
return(
<div>
<Navbar user = {user}/>
<div className="rides">
{updatedRides.map((ride) => {
return (
<div className="rideDetail">
<img src = {ride.map_url} alt="Ride_map" />
<div>
<p>Ride Id : {ride.id}</p>
<p>Origin Station : {ride.origin_station_code}</p>
<p>Station Path : {ride.station_path}</p>
<p>Date : {ride.date}</p>
<p>Distance : {ride.distance}</p>
</div>
</div>
)
})}
</div>
</div>
)
}
export default Rides;

我修复了你的代码,请查看这里https://codesandbox.io/embed/busy-payne-qiiw5r?fontsize=14&hidenavigation=1&theme=dark。问题与非async行为有关。在updaterides函数内的第二个useEffect中,您正在设置updatedRides,然后您正在映射它,但它不像您预期的那样工作,因为state更改不会在map之前立即更新。

import { useEffect, useState } from "react";
const Rides = () => {
const [rides, setRides] = useState([]);
const [user, setUser] = useState({});
const [updatedRides, setUpdatedRides] = useState([]);
useEffect(() => {
const fetchRides = async () => {
const data = await fetch("https://assessment.api.vweb.app/rides");
const json = await data.json();
setUpdatedRides(json);
setRides(json);
};
const fetchUser = async () => {
const data = await fetch("https://assessment.api.vweb.app/user");
const json = await data.json();
setUser(json);
};
const makeNetworkCalls = async () => {
await fetchRides();
await fetchUser();
};
makeNetworkCalls().catch((e) => {
console.log(e);
});
}, []);
useEffect(() => {
const calculateDistance = async (path, user_station) => {
let min = Math.abs(user_station - path[0]);
for (let i = 0; i < path.length; i++) {
if (path[i] === user_station) {
return 0;
}
if (Math.abs(path[i] - user_station) < min) {
min = Math.abs(path[i] - user_station);
}
}
return min;
};
const updaterides = async () => {
setUpdatedRides(rides);
updatedRides.map(async (ride) => {
ride.distance = await calculateDistance(
ride.station_path,
user.station_code
);
console.log(ride);
});
};
if (updatedRides?.length > 0 && rides?.length > 0) {
updaterides().catch((e) => {
console.log(e);
});
}
}, [rides, updatedRides]);
return (
<div>
<div className="rides">
{rides?.map((ride) => (
<div className="rideDetail">
<img src={ride.map_url} alt="Ride_map" />
<div>
<p>Ride Id : {ride.id}</p>
<p>Origin Station : {ride.origin_station_code}</p>
<p>Station Path : {ride.station_path}</p>
<p>Date : {ride.date}</p>
<p>Distance : {ride.distance}</p>
</div>
</div>
))}
</div>
</div>
);
};
export default Rides;

相关内容