Render FlowModel

FlowModelRenderer is the core React component for rendering a FlowModel. It is responsible for converting a FlowModel instance into a visual React component.

Basic Usage

FlowModelRenderer

import { FlowModelRenderer } from '@nocobase/flow-engine';

// Basic usage
<FlowModelRenderer model={myModel} />
/**
 * Example code demonstrating how to use NocoBase's plugin and model features.
 * - Defines a simple HelloModel that renders a "Hello, NocoBase!" UI block.
 * - Creates a plugin PluginHelloModel that registers the model and renders it via routing.
 * - Finally, loads the plugin through an Application instance and starts the app.
 */
import { Application, Plugin } from '@nocobase/client-v2';
import { FlowModelRenderer } from '@nocobase/flow-engine';


/**
 * PluginHelloModel is a plugin class that registers HelloModel and adds it to the router.
 * - The load method is executed when the plugin is loaded.
 * - Registers the model to flowEngine and creates a model instance.
 * - Renders the model instance at the root path '/' route.
 */
class PluginHelloModel extends Plugin {
  async load() {
    // Register HelloModel to flowEngine
    this.flowEngine.registerModelLoaders({
      HelloModel: {
        // Lazy import: the module is only loaded when this model is actually used for the first time
        loader: () => import('@docs/en/flow-engine/_demos/HelloModel'),
      },
     });

    // Create an instance of HelloModel (for demonstration only)
    const model = await this.flowEngine.createModelAsync({
      use: 'HelloModel',
    });

    // Add a route to render the model at the root path (for demonstration only)
    this.router.add('root', {
      path: '/',
      element: <FlowModelRenderer model={model} />,
    });
  }
}

// Create the application instance and register the plugin (for demonstration only)
const app = new Application({
  router: { type: 'memory', initialEntries: ['/'] },
  plugins: [PluginHelloModel],
});

export default app.getRootComponent();

FieldModelRenderer

For controlled field Models, use FieldModelRenderer to render:

import { FieldModelRenderer } from '@nocobase/flow-engine';

// Controlled field rendering
<FieldModelRenderer model={fieldModel} />

Props

FlowModelRendererProps

ParameterTypeDefaultDescription
modelFlowModel-The FlowModel instance to render
uidstring-The unique identifier for the flow model
fallbackReact.ReactNode<Skeleton.Button size="small" />Fallback content to display on rendering failure
showFlowSettingsboolean | objectfalseWhether to show the entry for flow settings
flowSettingsVariant'dropdown' | 'contextMenu' | 'modal' | 'drawer''dropdown'The interaction style for flow settings
hideRemoveInSettingsbooleanfalseWhether to hide the remove button in the settings
showTitlebooleanfalseWhether to display the model title in the top-left corner of the border
skipApplyAutoFlowsbooleanfalseWhether to skip applying auto flows
inputArgsRecord<string, any>-Extra context passed to useApplyAutoFlows
showErrorFallbackbooleantrueWhether to wrap the outermost layer with the FlowErrorFallback component
settingsMenuLevelnumber-Settings menu level: 1=current model only, 2=include child models
extraToolbarItemsToolbarItemConfig[]-Additional toolbar items

showFlowSettings Detailed Configuration

When showFlowSettings is an object, the following configurations are supported:

showFlowSettings={{
  showBackground: true,    // Show background
  showBorder: true,        // Show border
  showDragHandle: true,    // Show drag handle
  style: {},              // Custom toolbar style
  toolbarPosition: 'inside' // Toolbar position: 'inside' | 'above' | 'below'
}}

Rendering Lifecycle

The entire rendering cycle calls the following methods in order:

  1. model.dispatchEvent('beforeRender') - beforeRender event
  2. model.render() - Executes the model's render method
  3. model.onMount() - Component mount hook
  4. model.onUnmount() - Component unmount hook

Usage Examples

Basic Rendering

import { FlowModelRenderer } from '@nocobase/flow-engine';

function MyComponent() {
  const model = useFlowModel();
  
  return (
    <FlowModelRenderer 
      model={model}
      fallback={<div>Loading...</div>}
    />
  );
}

Rendering with Flow Settings

// Show settings but hide the remove button
<FlowModelRenderer
  model={myModel}
  showFlowSettings={true}
  hideRemoveInSettings={true}
/>

// Show settings and title
<FlowModelRenderer
  model={myModel}
  showFlowSettings={true}
  showTitle={true}
/>

// Use context menu mode
<FlowModelRenderer
  model={myModel}
  showFlowSettings={true}
  flowSettingsVariant="contextMenu"
  hideRemoveInSettings={true}
/>

Custom Toolbar

<FlowModelRenderer
  model={myModel}
  showFlowSettings={true}
  extraToolbarItems={[
    {
      key: 'custom-action',
      title: 'Custom Action',
      icon: 'SettingOutlined',
      onClick: () => {
        console.log('Custom action');
      }
    }
  ]}
/>

Skipping Auto Flows

<FlowModelRenderer
  model={myModel}
  skipApplyAutoFlows={true}
  showErrorFallback={false}
/>

Field Model Rendering

import { FieldModelRenderer } from '@nocobase/flow-engine';

function FormField({ model, onChange, ...props }) {
  return (
    <FieldModelRenderer
      model={model}
      onChange={onChange}
      {...props}
    />
  );
}

Error Handling

FlowModelRenderer has a comprehensive built-in error handling mechanism:

  • Automatic Error Boundary: showErrorFallback={true} is enabled by default
  • Auto Flow Errors: Catches and handles errors during the execution of auto flows
  • Rendering Errors: Displays fallback content when model rendering fails
<FlowModelRenderer
  model={myModel}
  showErrorFallback={true}
  fallback={<div>Rendering failed, please try again</div>}
/>

Performance Optimization

Skipping Auto Flows

For scenarios where auto flows are not needed, you can skip them to improve performance:

<FlowModelRenderer
  model={myModel}
  skipApplyAutoFlows={true}
/>

Reactive Updates

FlowModelRenderer uses the observer from @formily/reactive-react for reactive updates, ensuring that the component automatically re-renders when the model's state changes.

Notes

  1. Model Validation: Ensure the passed model has a valid render method.
  2. Lifecycle Management: The model's lifecycle hooks will be called at the appropriate times.
  3. Error Boundary: It is recommended to enable the error boundary in a production environment to provide a better user experience.
  4. Performance Consideration: For scenarios involving rendering a large number of models, consider using the skipApplyAutoFlows option.