Search code examples
reactjsreact-nativeexpo

React Native(Expo) SecureStore getItemAsync


I'm Using "expo-secure-store" to store JWT Token. when I try to get the data first it returns nothing and then the token.

my code:

const [api, ApiReply] = React.useState("");
const [isLoading, setLoading] = useState(true);

const [token, setToken] = React.useState("");

const clickHandler = () => {
    
    SecureStore.getItemAsync("secure_token").then((token) => setToken(token));
    console.log(token);
    
    var myHeaders = new Headers();
    myHeaders.append("Authorization", "Bearer " + token);
    
    var requestOptions = {
        method: "GET",
        headers: myHeaders,
    };

    fetch("http://193.119.10.206:3000/auth/user/8", requestOptions)
        .then((response) => response.text())
        .then((result) => ApiReply(JSON.parse(result)))
        .catch((d) => {
            alert("500");
        })
        .finally(() => setLoading(false));

};


React.useEffect(() => { 
    clickHandler();
}, [api])

I need the token when it's rendered. is there any solution or any alternative way?


Solution

  • There are three ways you can do this:

    1. move everything inside the then closure. This will wait for your get async function to finish before doing anything with the token.

       const clickHandler = () => {   
         SecureStore.getItemAsync("secure_token").then((token) => {
           setToken(token);
           console.log(token);
           var myHeaders = new Headers();
           myHeaders.append("Authorization", "Bearer " + token);
           var requestOptions = {
               method: "GET",
               headers: myHeaders,
           };
           fetch("http://193.119.10.206:3000/auth/user/8", requestOptions)
            .then((response) => response.text())
            .then((result) => ApiReply(JSON.parse(result)))
            .catch((d) => {
              alert("500");
            })
            .finally(() => setLoading(false));
            });
        };
      
    2. Use await instead:

       const clickHandler = async () => {
       const token = await SecureStore.getItemAsync("secure_token");
       setToken(token);
       console.log(token);
      
       var myHeaders = new Headers();
       myHeaders.append("Authorization", "Bearer " + token);
      
       var requestOptions = {
           method: "GET",
           headers: myHeaders,
       };
      
       fetch("http://193.119.10.206:3000/auth/user/8", requestOptions)
           .then((response) => response.text())
           .then((result) => ApiReply(JSON.parse(result)))
           .catch((d) => {
               alert("500");
           })
           .finally(() => setLoading(false));
      

    };

    1. utilize useEffect:

       const clickHandler = ()=>{
          SecureStore.getItemAsync("secure_token").then((token) => setToken(token));
       }
      

      useEffect(()=>{ if(token !== null) { //call fetch } },[token])