# State Management

In Goldfish, we can use Store Classes to manage states.

# AppStore

AppStore is the base class for managing the states of App.

You can create a class to extend the base AppStore:

import { AppStore } from '@goldfishjs/core';

export default class MyAppStore extends AppStore {
  // Put your codes here.
}
1
2
3
4
5

In the base class AppStore, there are some useful members.

# pluginHub

  • Protected

  • Type: PluginHub

  • Description:

    The pluginHub is used to manage all plugins. About the plugin system, you can refer it here.

# isInitLoading

# init()

  • Public

  • Lifecycle

  • Description:

    Called while the App is being initialized. More detailed, it is called in the onLaunch lifecycle of the App.

    You can override this method to add your own logic:




     
     
     
     
     


    import { AppStore } from '@goldfishjs/core';
    
    export default class MyAppStore extends AppStore {
      public init() {
        super.init();
    
        // Add your codes here.
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# fetchInitData()

  • Public

  • Lifecycle

  • Returns: A promise object to infer that all asynchronous tasks are finished.

  • description:

    fetchInitData() is used to execute asynchronous tasks like requesting data from server while initializing. This method is called in init(). During the method being executed, the isInitLoading is true, otherwise it is false.

















     
     
     
     
     
     
     
     
     


    import {
      AppStore,
      observable,
      state,
      RequesterPlugin,
    } from '@goldfishjs/core';
    
    export interface IStudent {
      name: string;
      age: number;
    }
    
    @observable
    export default class MyAppStore extends AppStore {
      public studentList: IStudent[] = [];
    
      async public fetchInitData() {
        await super.fetchInitData();
    
        const requesterPlugin = this.pluginHub.getPluginInstance(Requester);
        this.studentList = await requesterPlugin.request<IStudent[]>(
          'http://www.xxx.com',
          {},
        );
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

# getPlugins()

  • Public

  • Returns: A list of plugin classes.

  • Description:

    It is used to configure all the plugins that will be used in current App. The base getPlugins() method returns the inner plugin classes, and you should not remove this members in the derived getPlugins() method. But you can add new plugins:


















     
     
     
     
     
     


    import {
      AppStore,
      Plugin,
      GetPlugin,
    } from '@goldfishjs/core';
    
    class MyPlugin extends Plugin {
      public static type = 'myplugin';
    
      public init(getPlugin: GetPlugin) {
        // `getPlugin` can be used to access other registered plugins.
      }
    
      public destroy() {}
    }
    
    export default class MyAppStore extends AppStore {
      public getPlugins() {
        return [
          ...super.getPlugins(),
          MyPlugin,
        ];
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

# getPluginInstance()

  • Public

  • Arguments:

    • {PluginClass | string} pluginClass
  • Returns: The plugin instance of the pluginClass.

  • Description:

    Get the specified plugin instance from the registered plugins.





























     
     
     
     
     


    import {
      AppStore,
      Plugin,
      GetPlugin,
    } from '@goldfishjs/core';
    
    class MyPlugin extends Plugin {
      public static type = 'myplugin';
    
      public init(getPlugin: GetPlugin) {
        // `getPlugin` can be used to access other registered plugins.
      }
    
      public destroy() {}
    
      public bar() {
        console.log('bar');
      }
    }
    
    export default class MyAppStore extends AppStore {
      public getPlugins() {
        return [
          ...super.getPlugins(),
          MyPlugin,
        ];
      }
    
      public foo() {
        const myPlugin = this.getPluginInstance(MyPlugin);
        // Output: bar.
        myPlugin.bar();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

# waitForPluginsReady()

  • Public

  • Returns: A promise object to ensure that all plugins have been initialized.

  • Description:

    Wait for all the plugins returned by getPlugins() being initialized.




     
     
     
     


    import { AppStore } from '@goldfishjs/core';
    
    export default class MyAppStore extends AppStore {
      async public foo() {
        await this.waitForPluginsReady();
        console.log('All plugins have been initialized, and you can use them now.');
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

# waitForInitDataReady()

  • Public

  • Returns: A promise object to ensure that all asynchronous tasks have been finished.

  • Description:

    Wait for fetchInitData() being finished.




     
     
     
     
     


    import { AppStore } from '@goldfishjs/core';
    
    export default class MyAppStore extends AppStore {
      async public foo() {
        await this.waitForIniDataReady();
        // Output: false.
        console.log(this.isInitLoading);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# waitForReady()

  • Public

  • Returns: A promise object to ensure all plugins initializations and asynchronous tasks have completed.

  • Usage:




     
     
     
     



    import { AppStore } from '@goldfishjs/core';
    
    export default class MyAppStore extends AppStore {
      async public foo() {
        await this.waitForReady();
        // You can use plugins now and the init data is prepared.
      }
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# autorun()

  • Public

  • Arguments:

    • {AutorunFunction} fn
    • {IErrorCallback?} errorCb Called when there is some wrong with fn().
  • Returns: A function to stop listening to the dependency data changes.

  • Description:

    Auto executing the fn() when the reactive data in the fn() is changed.








     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     


    import { AppStore, observable, state } from '@goldfishjs/core';
    
    @observable
    export default class MyAppStore extends AppStore {
      @state
      public name: string = 'Yu Jiang';
    
      public foo() {
        this.autorun(() => {
          console.log(this.name);
        });
    
        setTimeout(
          () => {
            this.name = 'Dian Dao';
          },
          1000,
        );
    
        // Output:
        // Yu Jiang
        // Dian Dao
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

# watch()

  • Public

  • Arguments:

    • {IWatchExpressionFn} fn
    • {IWatchCallback} cb
    • {IWatchOptions?} options
      • {boolean?} deep Whether detect nested value changes inside reactive objects. Default is false.
      • {boolean?} immediate Whether to execute cb() immediately with the initial return value of fn().
      • {IErrorCallback?} onError Called when there is some thing wrong with fn() or cb().
  • Returns: A function to stop listening to the dependency data in fn().

  • Description:

    Call the cb() when the reactive data in the fn() is changed.








     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     


    import { AppStore, observable, state } from '@goldfishjs/core';
    
    @observable
    export default class MyAppStore extends AppStore {
      @state
      public name: string = 'Yu Jiang';
    
      public foo() {
        this.watch(
          () => this.name,
          () => {
            console.log('Enter,', this.name);
          },
        );
    
        setTimeout(
          () => {
            this.name = 'Dian Dao';
          },
          1000,
        );
    
        // Output:
        // Enter, Dian Dao
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

# PageStore

PageStore is the base class for managing the states of Page.

You can create a class to extend the base PageStore:

import { PageStore } from '@goldfishjs/core';

export default class MyPageStore extends PageStore {
  // Put your codes here.
}
1
2
3
4
5

In the base class PageStore, there are some useful members.

# globalStore

  • Public

  • Type: AppStore

  • Description:

    Reference to the global AppStore instance.

    You can specify the type of global store when create the subclass of PageStore:

    import { PageStore } from '@goldfishjs/core';
    import MyAppStore from '../../MyAppStore';
    
    export default class MyPageStore extends PageStore<MyAppStore> {
    }
    
    1
    2
    3
    4
    5

    Now, you can visit the extended members in MyAppStore with this.globalStore.myExtendedMember, and the TypeScript compiler does not complain.

# init()

# destroy()

  • Public

  • Lifecycle

  • Description:

    Called when the Page is destroyed.




     
     
     
     


    import { PageStore } from '@goldfishjs/core';
    
    export default class MyPageStore extends PageStore {
      public destroy() {
        super.destroy();
        // Put your destroy logic here.
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

# fetchInitData()

# autorun()

  • Public

  • Arguments:

    • {AutorunFunction} fn
    • {IErrorCallback?} errorCb
  • Returns: Function

  • Description:

    It is similar with AppStore#autorun(). If you do not stop the listening manually, it will be stopped when Page is destroyed.

# watch()

  • Public

  • Arguments:

    • {IWatchExpressionFn} fn
    • {IWatchCallback} cb
    • {IWatchOptions?} options
      • {boolean?} deep
      • {boolean?} immediate
      • {IErrorCallback?} onError
  • Returns: Function

  • Description:

    It is similar with AppStore#init(). If you do not stop the listening manually, it will be stopped when Page is destroyed.

# ComponentStore

ComponentStore is the base class for managing the states of Component.

You can create a class to extend the base ComponentStore:

import { ComponentStore } from '@goldfishjs/core';

export default class MyComponentStore extends ComponentStore<{}> {
  // Put your codes here.
}
1
2
3
4
5

In the base class ComponentStore, there are some useful members.

# props

  • Public

  • Type: object

  • Description:

    You should declare all component props here:














     
     
     
     


    import { ComponentStore, observable } from '@goldfishjs/core';
    import MyAppStore from '../../MyAppStore';
    
    export interface IProps {
      name?: string;
      age?: number;
    }
    
    @observable
    export default class MyComponentStore
      extends ComponentStore<IProps, MyAppStore>
    {
      @state
      public props = {
        name: undefined,
        age: undefined,
      };
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

# globalStore

  • Public

  • Type: AppStore

  • Description:

    Reference to the global AppStore instance.

    You can specify the type of global store when create the subclass of ComponentStore:

    import { PageStore } from '@goldfishjs/core';
    import MyAppStore from '../../MyAppStore';
    
    export default class MyPageStore extends PageStore<{}, MyAppStore> {
    }
    
    1
    2
    3
    4
    5

    Now, you can visit the extended members in MyAppStore with this.globalStore.myExtendedMember, and the TypeScript compiler does not complain.

# init()

# destroy()

  • Public

  • Lifecycle

  • Description:

    Called when the Component is destroyed.




     
     
     
     


    import { PageStore } from '@goldfishjs/core';
    
    export default class MyPageStore extends PageStore {
      public destroy() {
        super.destroy();
        // Put your destroy logic here.
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

# fetchInitData()

# autorun()

  • Public

  • Arguments:

    • {AutorunFunction} fn
    • {IErrorCallback?} errorCb
  • Returns: Function

  • Description:

    It is similar with AppStore#autorun(). If you do not stop the listening manually, it will be stopped when Component is destroyed.

# watch()

  • Public

  • Arguments:

    • {IWatchExpressionFn} fn
    • {IWatchCallback} cb
    • {IWatchOptions?} options
      • {boolean?} deep
      • {boolean?} immediate
      • {IErrorCallback?} onError
  • Returns: Function

  • Description:

    It is similar with AppStore#init(). If you do not stop the listening manually, it will be stopped when Component is destroyed.