skip to Main Content

I am creating a mobile application using react native & expo. In one of the setup pages on the app, it asks the user if they would like to allow the app to access their location. In the middle of the page there is a ‘share’ button, and at the bottom there is a ‘add later’.

What I would like to do is have the prompt for the location access to only appear when the ‘share’ button is clicked, rather than when the initial page is open. Giving users a chance to read the description first and choose an option.

This is my current code

//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>

3

Answers


  1. You are mixing some concepts of react. Here you are misusing useEffect and onPress callbacks. Is this your real code, as I think you left out some parts here. Note how you return (<Text>{JSON.stringify(location)}</Text>) for a onPress handler. Handlers should only perform logic, and not have anything related to components in them.

    Per the docs useEffect is a React Hook that lets you synchronize a component with an external system.

    It is commonly used to run code when a component mounts (first render) or when a state value updates to perform side effects. As you only want to run your code when a button is pressed you do not need to an useEffect here.

    Another issue you might have noticed is that your code runs immediately. This is because your are calling the function onPress={allowLocation()} instead of passing it as a callback. So either pass it by creating an arrow function or by leaving out the ():

    // option 1
    onPress={allowLocation}
    
    // option 2
    onPress={() => allowLocation()}
    

    So after you made these changes, your code should look something like this:

    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>
    )
    
    Login or Signup to reply.
  2. //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>
    )
    

    You should never initialize a hook inside a function. Hooks must be initialized at top level in a functional component.

    Login or Signup to reply.
  3. Dear Don’t need to use useEffect hook when calling location button click

    Try this, hope it will resolve your problem

    const [location, setLocation] = useState(null);
    
    const allowLocation = async () => {
    let { status } = await Location.requestForegroundPermissionsAsync();
    
    if (status === "granted") {
      console.log("Permission granted!");
      const loc = await Location.getCurrentPositionAsync();
      console.log(loc);
      setLocation(loc);
    } else {
      console.log("Permission not granted :(");
    }
    };
    
    return (
    <View>
      <View>
        <TouchableOpacity onPress={allowLocation}>
          <Text>Share</Text>
        </TouchableOpacity>
      </View>
      <Text>{JSON.stringify(location)}</Text>
    </View>
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search