我正在尝试将该类组件变成一个功能组件,该组件仅发送回经度和纬度。类组件确实给了我long / lat,但我想将其用作函数。该函数应只返回经度和纬度。
我试图使其内部具有这些函数,但是在navigator.getcurrent中调用了回调函数getCoords ....时,出现错误,表明未分配。
import React, { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
lat: '',
long: ''
};
}
getLocation = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.getCoords)
} else {
alert('GeoLocation not enabled');
}
}
getCoords = pos => {
console.log(pos)
this.setState({
lat: pos.coords.latitude,
long: pos.coords.longitude
})
}
render() {
return (
<div>
<button onClick={this.getLocation}>Click me</button>
<p>lat: {this.state.lat}</p>
<p>long {this.state.long}</p>
</div>
);
}
}
export default App;
我是否必须学习react hooks才能解决我的功能组件问题?
答案 0 :(得分:1)
使用钩子绝对是必经之路,这样您仍然可以将位置数据保持在状态。这是相同的代码,但带有useState钩子:
process
您会发现这并没有太大的区别,主要是删除const App = () => {
const [pos, setPos] = useState({lat: "", long: ""})
const getLocation = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(getCoords)
} else {
alert('GeoLocation not enabled');
}
}
const getCoords = (pos) => {
console.log(pos)
setPos({
lat: pos.coords.latitude,
long: pos.coords.longitude
})
}
return (
<div>
<button onClick={getLocation}>Click me</button>
<p>lat: {pos.lat}</p>
<p>long {pos.long}</p>
</div>
);
}
export default App;
和this
关键字,并用this.state
和pos.lat
替换它们。
从这里开始,如果您希望组件仅返回坐标而不是JSX,则可以创建自己的自定义钩子,如下所示:
setPos
答案 1 :(得分:0)
问题在于,通过导航器获取坐标是异步请求,因此在坐标可用之前就无法进行获取。使用useEffect
钩子,您可以告诉它一旦lat和long更新,就可以获取数据,如下所示:
const App = () => {
const pos = usePos()
useEffect(() => {
getDataWithCoords()
}, [pos.lat, pos.long])
const getDataWithCoords = () => {
fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${pos.lat},${pos.long}&key=YOUR_API_KEY`)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.log(err))
}
return (
<div>
<p>Lat {pos.lat}</p>
<p>Long: {pos.long}</p>
</div>
)
}
可能不是一个完美的例子,但它可以工作!
此外,请确保您没有公开发布API密钥,但您希望将这些密钥对您的本地开发环境保持私有。祝你好运!
答案 2 :(得分:0)
这更多地实现了DRY范例,我觉得这是一个相当理想的解决方案。
import React, { useEffect, useState } from 'react';
export function App() {
const [loc, setLoc] = useState({});
const [isLoaded, setIsLoaded = useState(false);
useEffect(() => {
const fetchMap = async () => {
const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${loc.lat},${loc.long}&key=${INSERT_API_KEY_HERE}`);
// Do something with the response
setIsLoaded(true);
};
fetchMap();
});
const getLocation = () => {
const { geolocation } = navigator;
if (geolocation) {
geolocation.getCurrentPosition(getCoordinates);
} else {
alert('GeoLocation not enabled');
}
};
const getCoordinates = (pos) => {
const { latitude, longitude } = pos.coords;
setLoc({ lat: latitude, long: longitude });
};
// You can this conditionalize your return statement based
// on the isLoaded state variable. "if (isLoaded)"
return (
<div>
<button onClick={getLocation}>Click me</button>
<p>lat: {loc.lat}</p>
<p>long {loc.long}</p>
</div>
);
};
export default App;