在本机反应中从asyncStorage检索数据

时间:2018-09-19 07:37:24

标签: reactjs react-native reactive-programming react-native-android

我知道有人问过类似的问题,例如this,但无法找到答案。我也是本机反应的新手。我需要从存储中检索数据,这就是我在API调用后存储值

的方式
_storeData = async response => {
 it AsyncStorage.setItem(token, (response))
  .then(() => {
  this.setState({
     shouldLoad : false
   });  
    console.log("Data saved successfully" + response);
    this.props.navigation.navigate("HomeScreen");
  })
  .catch(() => {
    console.log("There was an error saving the data");
  });
 };

这就是我尝试从 AsyncStorage

检索数据的方式
 AsyncStorage.getItem(token).then((token) => {
  this.setState({
    token : tokentoken,
    currentState : false
  });
});

试图实现的是会话管理。登录时,我将sessionToken保存到AsyncStorage,然后再次启动应用程序时,我需要取回数据。我尝试了不同的代码,但没有得到输出。

任何帮助将不胜感激 预先感谢

编辑1。

将全部代码粘贴到此处,以便任何人都可以指出哪里出了问题。

export default class App extends Component {
 constructor() {
super();
this.state = {
  token: null,
  currentState : true,
};
}

 componentDidMount() {
AsyncStorage.getItem(token).then((token) => {
  this.setState({
    token : tokentoken,
    currentState : false
  });
});
  }


  render() {
var ggg = this.state.token;
console.log(ggg);

if(this.state.currentState === false){

if (this.state.token === "" || this.state.token === null) {
  return <LoginNav />;
} else {
  return <HomeNavigatorNew />;
}

}

 else{
return (  <ActivityIndicator  
  animating={true}
    style={{ 
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',

      height: 80
    }}
    size="large"
  />)
  }
  }
 }

编辑2。

我在App.js中编写了上面的代码,我只是将整个代码移到了Login.js(另一个文件)中,它才起作用。那是什么意思。难道我应该在App.js中编写检索代码

编辑3。 感谢@Mohammed Ashfaq和@Samer Murad如此迅速的回应。 在Sammrs代码中,我注意到AsyncStorage是在大括号中导入的,而不是没有大括号。我没有它们就导入了。我在EDIT 2中提到过,该代码正在另一个文件中工作,其中AsyncStorage以大括号括起来。将修改后的工作代码留给他人参考

 import React, {Component} from "react";
 import   {AsyncStorage, ActivityIndicator} from "react-native";
 import { createStackNavigator} from "react-navigation";

 export default class App extends Component {
  constructor() {
   super();
   this.state = {
  token: null,
  currentState: true,
};
 }
  _retrieveData = async () => {
   console.log("Data retrieved successfully");

 // var tokenRetrieved = AsyncStorage.getItem('LoginTocken');
await AsyncStorage.getItem('LoginTocken')
  .then(value => { 
    return (value);
  })
  .then ( valueJson => {
    this.setState({
      token : valueJson,
      currentState : false
    });
    console.log("Data retrieved successfully", valueJson);
  })
  .catch((error) => {
    console.log("There was an error retrieving the data" + error);
  });



  };

  handleSession = async () => {
console.log("handleSession");
   this._retrieveData().catch((error) => {console.log("error is " + 
 error);});
  };

  componentWillMount() {
console.log("componentWillMount");
this.handleSession();
  }


  render() {


if (this.state.token === "" || this.state.token === null) {
  return <LoginNav / > ;
} else {
  return <HomeNavigatorNew / > ;
}
 }

}

我不知道为什么在不使用大括号的情况下完成某些导入**的原因以及它如何产生作用** {} **,其中有些操作是用括号完成的。如果有人知道为什么有时会省略/添加卷曲的括号,我要求他们留下答案。

2 个答案:

答案 0 :(得分:2)

这是我不久前写的一个LocalStorage包装器,它还包含在需要过期日期行为时在对象/键上设置TTL的功能,我将其用于与您相同的逻辑,这就是检查是否有保存的令牌,然后导航到主应用程序视图而不是登录页面。

这是包装纸:

import {AsyncStorage} from 'react-native'


/**
 *
 * @param key Key value of the object to be saved
 * @param object The Object to save
 * @param ttl (Optional) set an expiration date on an object in ms
 * @return {Promise<void>}
 */
export const setObjectForKey = async ({key, object, ttl = undefined }) => {

    if (!key) throw new Error('Cannot set an object without a key');

    if (!object) throw new Error('Cannot set a key without an object');

    let expiresAt = undefined;
    if (ttl) {
        expiresAt = new Date().getTime() + ttl;
    }
    let wrappedObj = {
        object,
        expiresAt,
    };
    let stringedWrapper = JSON.stringify(wrappedObj);

    return await AsyncStorage.setItem(key,stringedWrapper)
};


/**
 *
 * @param key The key of the object to remove
 * @return {Promise<void>}
 */
export const removeObjectForKey = async (key) => {
    return await AsyncStorage.removeItem(key)
};


/**
 *
 * @param key The key of the object to retrieve
 * @return {Promise<*>}
 */
export const getObjectForKey = async (key) => {
    let now = new Date().getTime();
    let stringedWrapper = await AsyncStorage.getItem(key);

    if (!stringedWrapper) throw new Error('No key found for object');

    let wrapper = JSON.parse(stringedWrapper);
    if (wrapper.expiresAt < now) {
        // Object expired
        AsyncStorage.removeItem(key);
        throw new Error('Object expired');
    } else {
        return wrapper.object;
    }
};

这是一个用法示例(在我的解决方案中,我有一个Redux中间件,因此在检索对象后我称为Dispatch):

获取:

let key = 'APP_TOKEN';
localstorage.getObjectForKey(key)
            .then((retrievedObject) => {
               // Do what you want with object
            })
            .catch((err) => {
               // Handle error, Object either doesn't exist, expired or a system error
            })

设置:

 let key = 'APP_TOKEN';
 let object = {token: 'JWT_HASH'};
 let ttl = undefinded // TTL is optional
 localstorage.setObjectForKey({
            key,
            object,
            ttl,
        })
            .then(() => {
               // Set was successfull
            })
            .catch((err) => {
                // Handle Error
            })

删除:

localstorage.removeObjectForKey(key)
            .then(() => {
              // Successfully deleted
            })
            .catch((err) => {
               // Object either doesn't exist to delete or system error
            })

请注意,我实际上保存了要进行字符串化的对象,因此,即使保存了api令牌,我也确实将带有令牌的对象保存为键,即:{token: 'TOKEN'}

希望有帮助

答案 1 :(得分:1)

 /* Login Screen */

async storeSessionToken(token) {
  try {
    await AsyncStorage.setItem('token', token);
    console.log("Data saved successfully");
    // Rest of your code
  } catch (error) {
    console.log("Error while storing the token");
  }
}




/* Splash Screen  */ 

async retrieveSessionToken() {
  try {
    const token = await AsyncStorage.getItem('token');
    if (token !== null) {
      console.log("Session token",token );
      return token;
    }
   } catch (error) {
     console.log("Error while storing the token");
   }
}



// calling retrieveSessionToken
componentDidMount() {
  this.retrieveSessionToken()
  .then((token)=> { 
    if(token) this.setState({token: token})
  })
}