singleton object in react native

前端 未结 5 1880
慢半拍i
慢半拍i 2020-12-13 08:56

I\'m new in react native.I want store multiple small small strings to common singleton object class and want to access it from singleton object for all component. Can anyone

相关标签:
5条回答
  • 2020-12-13 09:48

    I might be too late for this, but I might as well share my own implementation based on Yeshan Jay's answer.

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

    And here's how you use it. It's pretty much mimicking React Component's state behavior, so you should feel at home with little to no adjustment, without the need to frequently modify the Singleton to add new properties now and then.

    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) 
    
    0 讨论(0)
  • 2020-12-13 09:50

    Here is a simple way of doing it...

    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;
        }
    }
    

    And here is how to use it...

    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);
    

    Hope this works out for you :)

    0 讨论(0)
  • 2020-12-13 09:56

    I suggest making a static class that stores data using AsyncStorage. You mentioned in a comment that you are already using AsyncStorage, but don't like spreading this functionality throughout your app. (i.e. try-catches all over the place, each component needing to check if a key is available, etc.) If this functionality were in a single class, it would clean up your code a lot.

    Another bonus to this approach is that you could swap out the implementation pretty easily, for example, you could choose to use an in-memory object or AsyncStorage or whatever and you would only have to change this one file

    NOTE: AsyncStorage is not a safe way to store sensitive information. See this question for more info on the security of AsyncStorage and alternatives.

    That said, this is how I imagine a global data holder class might look:

    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...
    }
    

    Then to use this class anywhere in your app, just import wherever it's needed like so:

    import dataManager from 'path/to/dataManager.js';
    
    // store value
    dataManager.storeKeyValue('myKey', 'myValue');
    
    // get value
    const storedValue = dataManager.getValueForKey('myKey');
    

    EDIT: Using Flux, Redux, or a similar technology is probably the preferred/suggested way to do this in most cases, but if you feel the Singleton pattern works best for your app then this is a good way to go. See You Might Not Need Redux

    0 讨论(0)
  • 2020-12-13 10:02

    There is a workaround for this, react native packager require all the modules in the compilation phase for a generating a bundle , and after first require it generates an internal id for the module, which is from then on referenced in the whole run-time memory , so if we export an instance of a class from the file, that object will be referenced every-time whenever that file is imported .

    TLDR;

    Solution I :

    class abc {
    
    }
    
    
    module.exports = new abc()
    

    Solution II : I assume you want to get your strings which are static and wont change , so you can declare them as static and access them directly with class name

    FYI :this works with webpack also.

    0 讨论(0)
  • 2020-12-13 10:02

    TS Class Example:

    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.");
            }
        }
    }
    

    Use:

    SingletonClass.getInstance().anyMetod(1);
    
    0 讨论(0)
提交回复
热议问题