英文:
React useState and useEffect does not work as expected
问题
我有一个状态用于存储对象和两个useEffect
。第一个useEffect
仅在首次渲染时执行,而第二个useEffect
会在toFetch
状态发生变化时执行。此外,toFetch
有一个初始值,即安卡拉的坐标,存储在对象中。首先,useEffect
用于确定用户是否已授予地理位置权限。如果已经授予权限,它将获取当前位置;如果没有授权,它将不执行任何操作。这时,第二个useEffect
生效,基本上从API获取数据并设置"selected"状态。然而,当用户允许地理位置权限时,"selected"状态仍然使用安卡拉的坐标。问题是什么?
以下是您的代码:
function Contex({ children }) {
let obj = { lat: 39.57, lng: 32.53 }; // 安卡拉的坐标
const [weather, setWeather] = useState([]);
const [selected, setSelected] = useState({});
const [toFetch, settoFetch] = useState(obj);
const [loading, setloading] = useState(false);
useEffect(() => {
const initialSetup = () => {
const successCallback = (pos) => {
const {
coords: { latitude, longitude },
} = pos;
settoFetch((prev) => {
return { type: "single", lat: latitude, lng: longitude };
});
};
const errorCallback = (err) => {};
navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {
enableHighAccuracy: true,
});
};
initialSetup();
}, []);
useEffect(() => {
const fetchData = async () => {
setloading(true);
let x = toFetch;
if (toFetch.type === "country") x = await getCountryStates(toFetch.name);
const weatherData = await dataProvider([x].flat());
setWeather(weatherData);
setSelected(weatherData[0]);
setloading(false);
};
fetchData();
}, [toFetch]);
return (
<context.Provider
value={{
weather,
setSelected,
selected,
settoFetch,
loading,
toFetch,
}}
>
{children}
</context.Provider>
);
}
export { Contex, context };
编辑 1:
我尝试过将地理位置作为Promise使用,但也没有成功。请帮助。
英文:
I have one state for storing an object and two useffects. The first useeffect occurs only once in the first render, while the second occurs whenever the 'toFetch' state is changed. In addition, has an initial value for toFetch that is the coordinates of Ankara and is stored in object. First, useffect determines whether the user has granted permission for geolocation. If allowed, it is set to fetch the current location; if it is not, it does nothing. This time, the second useffect works. and basically fetches data from the API and sets the "selected" state. However, when the user allows geolocation, the selected state continues to use Ankara coordinates. What is the problem?
Here is my Code
function Contex({ children }) {
let obj = { lat: 39.57, lng: 32.53 }; // coordinates of ankara
const [weather, setWeather] = useState([]);
const [selected, setSelected] = useState({});
const [toFetch, settoFetch] = useState(obj);
const [loading, setloading] = useState(false);
useEffect(() => {
const initialSetup = () => {
const sb = (pos) => {
const {
coords: { latitude, longitude },
} = pos;
settoFetch((prev) => {
return { type: "single", lat: latitude, lng: longitude };
});
};
const eb = (err) => {};
navigator.geolocation.getCurrentPosition(sb, eb, {
enableHighAccuracy: true,
});
};
initialSetup();
}, []);
useEffect(() => {
const den = async () => {
setloading(true);
let x = toFetch;
if (toFetch.type === "country") x = await getCountryStates(toFetch.name);
const weatherData = await dataProvider([x].flat());
setWeather(weatherData);
setSelected(weatherData[0]);
setloading(false);
};
den();
}, [toFetch]);
return (
<context.Provider
value={{
weather,
setSelected,
selected,
settoFetch,
loading,
toFetch,
}}
>
{children}
</context.Provider>
);
}
export { Contex, context };
Edit 1:
I tried to use geolocation as promise but it also did not work. Please help
答案1
得分: 1
function Contex({ children }) {
let obj = { lat: 39.57, lng: 32.53 }; // coordinates of ankara
const [weather, setWeather] = useState([]);
const [selected, setSelected] = useState({});
const [toFetch, settoFetch] = useState(obj);
const [loading, setloading] = useState(false);
useEffect(() => {
const initialSetup = () => {
const sb = (pos) => {
const {
coords: { latitude, longitude },
} = pos;
settoFetch((prev) => {
return { type: "single", lat: latitude, lng: longitude };
});
};
const eb = (err) => {};
navigator.geolocation.getCurrentPosition(sb, eb, {
enableHighAccuracy: true,
});
};
initialSetup();
}, []);
useEffect(() => {
const den = async () => {
setloading(true);
let x = toFetch;
if (toFetch.type === "country") x = await getCountryStates(toFetch.name);
const weatherData = await dataProvider([x].flat());
setWeather(weatherData);
setSelected(weatherData[0]);
setloading(false);
};
den();
}, [toFetch.lat, toFetch.lng]);
return (
<context.Provider
value={{
weather,
setSelected,
selected,
settoFetch,
loading,
toFetch,
}}
>
{children}
</context.Provider>
);
}
export { Contex, context };
英文:
function Contex({ children }) {
let obj = { lat: 39.57, lng: 32.53 }; // coordinates of ankara
const [weather, setWeather] = useState([]);
const [selected, setSelected] = useState({});
const [toFetch, settoFetch] = useState(obj);
const [loading, setloading] = useState(false);
useEffect(() => {
const initialSetup = () => {
const sb = (pos) => {
const {
coords: { latitude, longitude },
} = pos;
settoFetch((prev) => {
return { type: "single", lat: latitude, lng: longitude };
});
};
const eb = (err) => {};
navigator.geolocation.getCurrentPosition(sb, eb, {
enableHighAccuracy: true,
});
};
initialSetup();
}, []);
useEffect(() => {
const den = async () => {
setloading(true);
let x = toFetch;
if (toFetch.type === "country") x = await getCountryStates(toFetch.name);
const weatherData = await dataProvider([x].flat());
setWeather(weatherData);
setSelected(weatherData[0]);
setloading(false);
};
den();
}, [toFetch.lat, toFetch.lng]); // Using an object in your useEffect dependency array also causes the infinite loop problem.
return (
<context.Provider
value={{
weather,
setSelected,
selected,
settoFetch,
loading,
toFetch,
}}
>
{children}
</context.Provider>
);
}
export { Contex, context };
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论