Skip to content

State Management Selectors

Rdmclin2 edited this page Nov 5, 2024 · 1 revision

Data Storage and Retrieval Module

Selectors are the data retrieval module under the LobeVidol data flow development framework. Their purpose is to extract data from the store using specific logic for component consumption.

Taking src/store/tool/slices/plugin/selectors.ts as an example:

This TypeScript code snippet defines an object named pluginSelectors, which contains a series of selector functions used to retrieve data from the plugin storage state. Selectors are functions that extract and derive data from Zustand. This particular example is designed to manage the state related to the plugin system of the front-end application.

Here are some key points explained:

  • getCustomPluginById: Returns custom plugin information based on the plugin ID.
  • getInstalledPluginById: Returns information about the installed plugin based on the plugin ID.
  • getPluginManifestById: Returns the plugin manifest based on the plugin ID.
  • getPluginMetaById: Returns plugin metadata based on the plugin ID.
  • getPluginSettingsById: Returns plugin settings based on the plugin ID.
  • installedCustomPluginMetaList: Returns a list of metadata for all installed custom plugins.
  • installedPluginManifestList: Returns a list of manifests for all installed plugins.
  • installedPluginMetaList: Returns a list of metadata for all installed plugins.
  • installedPlugins: Returns a list of all installed plugins.
  • isPluginHasUI: Determines whether a plugin has a UI component based on the plugin ID.
  • isPluginInstalled: Checks if a plugin is installed based on the plugin ID.
  • storeAndInstallPluginsIdList: Returns a list of all IDs from the store and installed plugins.

Selectors encapsulate complex state selection logic within separate functions, making the code cleaner and more intuitive when calling state data in other parts of the application. Additionally, since TypeScript is used, each function can have clearly defined input and output types, which helps improve code reliability and development efficiency.

In components, you can simply import the relevant selectors to directly access the data for consumption:

import { useToolStore } from '@/store/tool';
import { pluginSelectors } from '@/store/tool/selectors';

const Render = () => {
  const list = useToolStore(pluginSelectors.installedPluginMetaList);

  return <> ... </>;
};

The benefits of this implementation include:

  1. Decoupling and Reusability: By keeping selectors independent of components, we can reuse these selectors across multiple components without rewriting the data retrieval logic. This reduces code duplication, enhances development efficiency, and makes the codebase cleaner and easier to maintain.
  2. Performance Optimization: Selectors can be used to compute derived data, avoiding the need to recalculate the same data in each component. When the state changes, only the selectors that depend on that part of the state will be recalculated, reducing unnecessary renders and computations.
  3. Ease of Testing: Selectors are pure functions that only depend on the parameters passed to them. This means they can be tested in isolation without needing to mock the entire store or component tree.
  4. Type Safety: Since LobeVidol uses TypeScript, each selector has clearly defined input and output types. This provides developers with the advantages of autocompletion and compile-time checks, reducing runtime errors.
  5. Maintainability: Selectors centralize the logic for reading state, making it more intuitive to track state changes and manage them. If the state structure changes, we only need to update the relevant selectors instead of searching and replacing multiple locations throughout the codebase.
  6. Composability: Selectors can compose other selectors to create more complex selection logic. This pattern allows developers to build a hierarchy of selectors, making state selection more flexible and powerful.
  7. Simplified Component Logic: Components do not need to know the structure of the state or how to retrieve and compute the required data. Components simply call selectors to get the data needed for rendering, making the component logic simpler and clearer.

With this design, LobeVidol developers can focus more on building user interfaces and business logic without worrying about the details of data retrieval and processing. This pattern also provides better adaptability and extensibility for potential future changes in the state structure.