如何在其他文件中使用导出常量中的变量?
How to use variables from exported constants in other files?
我将此导出 const
到一个文件 useLocation.tsx
中,我在其中获取用户的位置并检索用户的县、state/province 和国家/地区。我还在另一个文件 useCountryData.tsx
中导出了 const
,我从 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 来执行更传统的异步操作,然后是 'hook-style' 模式,它执行 useState 和 useEffect 来制作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 运行s。
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 };
};
我将此导出 const
到一个文件 useLocation.tsx
中,我在其中获取用户的位置并检索用户的县、state/province 和国家/地区。我还在另一个文件 useCountryData.tsx
中导出了 const
,我从 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 来执行更传统的异步操作,然后是 'hook-style' 模式,它执行 useState 和 useEffect 来制作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 运行s。
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 };
};