【发布时间】:2017-11-26 21:30:33
【问题描述】:
我是 react native 的新手。我想将多个小字符串存储到常见的单例对象类中,并希望从所有组件的单例对象中访问它。任何人都可以帮我实现反应原生的单例对象。
前
组件 1 -- 登录按钮 -- >> 成功 --> 需要将用户 ID 存储到单例对象中。
组件 2 --> 从单例对象中获取存储的用户 ID。我该如何实现它。
【问题讨论】:
标签: react-native
我是 react native 的新手。我想将多个小字符串存储到常见的单例对象类中,并希望从所有组件的单例对象中访问它。任何人都可以帮我实现反应原生的单例对象。
前
组件 1 -- 登录按钮 -- >> 成功 --> 需要将用户 ID 存储到单例对象中。
组件 2 --> 从单例对象中获取存储的用户 ID。我该如何实现它。
【问题讨论】:
标签: react-native
TS 类示例:
export class SingletonClass
{
private static _instance: SingletonClass;
public anyMetod(_value:any):any
{
return _value;
}
public static getInstance(): SingletonClass
{
if (SingletonClass._instance == null)
{
SingletonClass._instance = new SingletonClass();
}
return this._instance;
}
constructor()
{
if(SingletonClass._instance)
{
throw new Error("Error: Instantiation failed: Use SingletonClass.getInstance() instead of new.");
}
}
}
用途:
SingletonClass.getInstance().anyMetod(1);
【讨论】:
我可能为时已晚,但我不妨根据 Yeshan Jay 的回答分享我自己的实现。
export default class Data {
static instance = null;
_state = {};
static get inst() {
if (Data.instance == null) {
Data.instance = new Data();
}
return this.instance;
}
static get state() {
return Data.inst._state;
}
static set state(state) {
Data.inst._state = state;
}
static setState(state) {
Data.inst._state = {...Data.inst._state, ...state}
}
}
这就是你如何使用它。它几乎模仿了 React 组件的状态行为,因此您应该感到宾至如归,几乎无需调整,无需经常修改 Singleton 以不时添加新属性。
import Data from './Data'
// change the whole singleton data
Data.state = { userId: "11231244", accessToken: "fa7sd87a8sdf7as" }
// change only a property
Data.setState ({ userId: "1231234" })
// get a single property directly
console.log("User Id: ", Data.state.userId)
// get a single property or more via object deconstruction
const { userId, property } = Data.state
console.log("User Id: ", userId)
【讨论】:
这是一个简单的方法......
export default class CommonDataManager {
static myInstance = null;
_userID = "";
/**
* @returns {CommonDataManager}
*/
static getInstance() {
if (CommonDataManager.myInstance == null) {
CommonDataManager.myInstance = new CommonDataManager();
}
return this.myInstance;
}
getUserID() {
return this._userID;
}
setUserID(id) {
this._userID = id;
}
}
这里是如何使用它...
import CommonDataManager from './CommonDataManager';
// When storing data.
let commonData = CommonDataManager.getInstance();
commonData.setUserID("User1");
// When retrieving stored data.
let commonData = CommonDataManager.getInstance();
let userId = commonData.getUserID();
console.log(userId);
希望这对你有用:)
【讨论】:
AsyncStorage。我上面所做的是内存中的临时存储。你也可以看看这个..react-native-storage
let关键字改成var看看..我认为这是一个旧版本的js引擎。
return this.myInstance;
我建议创建一个使用AsyncStorage 存储数据的静态类。
您在评论中提到您已经在使用AsyncStorage,但不喜欢在您的应用程序中传播此功能。 (即到处都是try-catches,每个组件都需要检查密钥是否可用等)如果这个功能在一个类中,它会清理你的代码很多。
这种方法的另一个好处是您可以很容易地换出实现,例如,您可以选择使用内存中的对象或AsyncStorage 或其他任何东西,您只需要更改这个文件
注意:AsyncStorage不是存储敏感信息的安全方式。请参阅this question,了解有关AsyncStorage 和替代方案的安全性的更多信息。
也就是说,这就是我想象的全局数据持有者类的样子:
export default class dataManager {
static storeKeyValue(key, value) {
// your choice of implementation:
// check if key is used
// wrap in try-catch
// etc.
}
static getValueForKey(key) {
// get the value out for the given key
}
// etc...
}
然后要在您的应用中的任何地方使用这个类,只需像这样在需要的地方导入:
import dataManager from 'path/to/dataManager.js';
// store value
dataManager.storeKeyValue('myKey', 'myValue');
// get value
const storedValue = dataManager.getValueForKey('myKey');
编辑:在大多数情况下,使用 Flux、Redux 或类似技术可能是首选/建议的方法,但如果您觉得单例模式最适合您的应用程序那么这是一个很好的方法。 见You Might Not Need Redux
【讨论】:
有一个解决方法,在编译阶段对原生打包器require所有模块进行反应以生成一个包,并在首先要求它为模块生成一个内部id之后,从那时起在整个运行时内存,因此,如果我们从文件中导出类的实例,则每次导入该文件时都会引用该对象。
TLDR;
解决方案一:
class abc {
}
module.exports = new abc()
解决方案二:我假设您想要获取静态且不会更改的字符串,因此您可以将它们声明为静态并使用类名直接访问它们
仅供参考:这也适用于 webpack。
【讨论】: