我正在使用 React Native 和 Expo 创建一个移动应用程序。在应用程序的设置页面之一中,它会询问用户是否允许应用程序访问他们的位置。页面中间有一个“分享”按钮,底部有一个“稍后添加”。
我想做的是仅在单击“共享”按钮时出现位置访问提示,而不是在打开初始页面时出现。让用户有机会先阅读说明并选择一个选项。
这是我当前的代码
//Allow access to location function
const [location, setLocation] = useState(null);
function allowLocation() {
useEffect(() => {
(async() => {
let {status} = await Location.requestForegroundPermissionsAsync()
if (status == 'granted') {
console.log('Permission granted!')
} else {
console.log('Permission not granted :(')
}
const loc = await Location.getCurrentPositionAsync()
console.log(loc)
setLocation(loc)
})();
}, []);
return (<Text>{JSON.stringify(location)}</Text>)
}
//Calling the function in the return statement of the main app function
<View>
<View>
<TouchableOpacity onPress={allowLocation()}>
<Text>Share</Text>
</TouchableOpacity>
</View>
</View>
您正在混合一些反应概念。在这里,您滥用了
useEffect
和 onPress
回调。这是你真正的代码吗,因为我认为你在这里遗漏了一些部分。请注意如何为 (<Text>{JSON.stringify(location)}</Text>)
处理程序返回 onPress
。处理程序应该只执行逻辑,而不包含与其中的组件相关的任何内容。
useEffect
是一个 React Hook,可让您将组件与外部系统同步。
它通常用于在组件安装(首次渲染)或状态值更新以执行副作用时运行代码。由于您只想在按下按钮时运行代码,因此不需要此处的
useEffect
。
您可能注意到的另一个问题是您的代码会立即运行。这是因为您正在调用函数
onPress={allowLocation()}
而不是将其作为回调传递。因此,要么通过创建箭头函数来传递它,要么省略 ()
:
// option 1
onPress={allowLocation}
// option 2
onPress={() => allowLocation()}
因此,在进行这些更改后,您的代码应如下所示:
const [location, setLocation] = useState(null);
// to allow for `await`, mark the function as async
async function allowLocation() {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status == 'granted') {
console.log('Permission granted!');
} else {
console.log('Permission not granted :(');
}
const loc = await Location.getCurrentPositionAsync();
console.log(loc);
// make sure you handle when locations are not allowed by the user
setLocation(loc);
}
return (
<View>
<TouchableOpacity onPress={allowLocation}>
<Text>Share</Text>
</TouchableOpacity>
</View>
)
//Allow access to location function
const [location, setLocation] = useState(null);
const allowLocation = async () => {
let {status} = await Location.requestForegroundPermissionsAsync()
if (status == 'granted') {
console.log('Permission granted!')
} else {
console.log('Permission not granted :(')
}
const loc = await Location.getCurrentPositionAsync()
console.log(loc)
setLocation(loc)
}
//Calling the function in the return statement of the main app function
return (
<View>
<View>
<TouchableOpacity onPress={allowLocation}>
<Text>Share</Text>
</TouchableOpacity>
</View>
</View>
)
永远不应该在函数内初始化钩子。钩子必须在功能组件的顶层初始化。