如何解决如何使用其他文件中导出的常量中的变量?
我将这个导出的 const
保存在一个文件 useLocation.tsx
中,我可以在其中获取用户的位置并检索用户的县、州/省和国家/地区。我还在另一个文件 const
中导出了 useCountryData.tsx
,我在其中从 API 获取 COVID 病例和死亡人数。 useLocation.tsx
中有一个名为 countryNameshort
的变量。如何在 useCountryData.tsx
中使用此变量?
useLocation.tsx
export const useLocation = () => {
var [stateName,setstateName] = useState(String);
var [countyName,setCountyName] = useState(String);
var [countryName,setCountryName] = useState(String);
var [stateNameshort,setstateNameshort] = useState(String);
var [countryNameshort,setCountryNameshort] = useState(String);
const [latitude,setlatitude] = useState(Number);
const [longitude,setlongitude] = useState(Number);
const [location,setLocation] = useState(Object);
const [errorMsg,setErrorMsg] = useState(String);
useEffect(() => {
(async () => {
if (Platform.OS === "android" && !Constants.isDevice) {
setErrorMsg(
"Oops,this will not work on Snack in an Android emulator. Try it on your device!"
);
return;
}
let { status } = await Location.requestPermissionsAsync();
if (status !== "granted") {
setErrorMsg("Permission to access location was denied");
return;
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
const latitude = location.coords.latitude;
setlatitude(latitude);
const longitude = location.coords.longitude;
setlongitude(longitude);
})();
},[]);
let text = "Waiting..";
if (errorMsg) {
text = errorMsg;
} else if (location) {
text = JSON.stringify(location);
}
fetch(
"https://maps.googleapis.com/maps/api/geocode/json?address=" +
latitude +
"," +
longitude +
"&key=" +
apiKey
)
.then((response) => response.json())
.then((responseJson) => {
const resstate = responseJson.results[0].address_components.filter(
(x: any) =>
x.types.filter((t: Object) => t == "administrative_area_level_1")
.length > 0
)[0].long_name;
setstateName(resstate);
const resCounty = responseJson.results[0].address_components.filter(
(x: any) =>
x.types.filter((t: Object) => t == "administrative_area_level_2")
.length > 0
)[0].long_name;
setCountyName(resCounty);
const resCountry = responseJson.results[0].address_components.filter(
(x: any) => x.types.filter((t: Object) => t == "country").length > 0
)[0].long_name;
setCountryName(resCountry);
const resstateShort = responseJson.results[0].address_components.filter(
(x: any) =>
x.types.filter((t: Object) => t == "administrative_area_level_1")
.length > 0
)[0].short_name;
setstateNameshort(resstateShort);
const resCountryShort = responseJson.results[0].address_components.filter(
(x: any) => x.types.filter((t: Object) => t == "country").length > 0
)[0].short_name;
setCountryNameshort(resCountryShort);
if (countryNameshort === "US") {
countryNameshort = "US" + "A";
}
})
.catch((err) => {
console.log(err);
});
return { countryName,countyName,stateName,stateNameshort,countryNameshort };
};
useCountryData.tsx
import { useLocation } from './useLocation';
export const useCountryData = () => {
const [earliest2,setEarliest2] = useState([]);
const [countryDeaths,setcountryDeaths] = useState(Number);
const [countryCases,setcountryCases] = useState(Number);
useEffect(() => {
axios
.get("https://coronavirus-19-api.herokuapp.com/countries")
.then((response) => {
setEarliest2(response.data);
const countryArray = response.data.filter(
(item) => item.country === props.countryNameshort //???
);
const resCountryDeaths = countryArray[0].deaths;
setcountryDeaths(resCountryDeaths);
const resCountryCases = countryArray[0].cases;
setcountryCases(resCountryCases);
console.log("hiiii",countryCases);
})
.catch((err) => {
console.log(err);
});
},[]);
return { countryCases,countryDeaths };
};
CountryCard.tsx
const CountryCard = (props) => {
const mappedLocation = useMappedLocation();
const countryName = mappedLocation.country;
return (
<RectButton style={[styles.container,{ backgroundColor: "white" }]}>
<Text style={[styles.textLocation,{ top: 15,left: 10 }]}>
{countryName} /???
</Text>
)
}
解决方法
这是一个关于如何重构这些阶段的伪代码建议,而不是采用 useEffect 和 useState 来执行更传统的只是异步的操作,然后是使用 useState 和 useEffect 来实现异步的“hook-style”模式结果可用于您的 UI。这段代码根本不可能运行,因为我无法访问您的环境来真正尝试它,但它可以让您了解如何重构它。如果状态需要被 UI 的多个部分使用,那么 useMappedLocation 钩子在祖先组件中分配一个 MappedLocation 变量是有意义的,结果通过 Context、Composition 或 Props 传递给后代。这将具有缓存结果的效果。
我还勾勒出第二个钩子如何消耗第一个钩子,因为我认为重新阅读了您的问题,这是您坚持原来方法的重点。然而,在多个地方嵌入 useMappedLocation 钩子会导致它被多次重新执行,并且与将其提升到祖先组件中相比不会从缓存中受益。
const apikey = "myapikey";
interface GeoEntry {
address_components:[
{types:("country"|"administrative_area_level_1")[]
short_name:string,long_name:string
}
]
}
interface MappedLocation {
state:string,country:string
}
async function getLocation(){
return await Location.getCurrentPositionAsync({});
}
async function getFirstGeoEntry() : Promise<GeoEntry>{
const {latitude,longitude} = await getLocation();
const response = await fetch(
"https://maps.googleapis.com/maps/api/geocode/json?address=" +
latitude +
"," +
longitude +
"&key=" +
apikey
)
const json = await response.json();
return json.results[0]
}
function getStateNameLong(geoEntry:GeoEntry){
return geoEntry.address_components.filter(
(x: any) =>
x.types.filter((t: Object) => t == "administrative_area_level_1")
.length > 0
)[0].long_name
}
function getCountryNameShort(geoEntry:GeoEntry){
return geoEntry.address_components.filter(
(x: any) => x.types.filter((t: Object) => t == "country").length > 0
)[0].short_name
}
async function getMappedLocation() : Promise<MappedLocation>{
const geoEntry = await getFirstGeoEntry();
return {
country:getCountryNameShort(geoEntry),state:getStateNameLong(geoEntry),}
}
const useMappedLocation = () => {
const [mappedLocation,setMappedLocation] = useState<MappedLocation>(null);
useEffect(() => {
(async () => {
setMappedLocation(await getMappedLocation())
})()
},[])
return mappedLocation
}
以下是第二个钩子 ( useCountryData ) 可能使用第一个 ( useMappedLocation ) 的方式。请注意,useEffect 处理位置尚未到达的情况,而mappedLocation 位于依赖项数组中,以确保在mappedLocation 最终到达时useEffect 再次运行。
import { useMappedLocation } from './useMappedLocation';
export const useCountryData = () => {
const [earliest2,setEarliest2] = useState([]);
const [countryDeaths,setcountryDeaths] = useState(Number);
const [countryCases,setcountryCases] = useState(Number);
const mappedLocation = useMappedLocation()
useEffect(() => {
if(mappedLocation !== null){
axios.get("https://coronavirus-19-api.herokuapp.com/countries")
.then((response) => {
setEarliest2(response.data);
const countryArray = response.data.filter(
(item) => item.country === mappedLocation.country
);
const resCountryDeaths = countryArray[0].deaths;
setcountryDeaths(resCountryDeaths);
const resCountryCases = countryArray[0].cases;
setcountryCases(resCountryCases);
console.log("hiiii",countryCases);
})
.catch((err) => {
console.log(err);
});
}
},[mappedLocation]);
return { countryCases,countryDeaths };
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。