hooks.ts


Overview

The hooks.ts file defines a custom React hook named useHandleOperateParameters designed to manage and manipulate parameter variables related to a specific node within a graph-like data structure. This hook provides a set of utility functions to add, remove, update, and save parameters (variables) associated with a node identified by nodeId. It leverages state management via a store (useGraphStore), React hooks for memoization and callbacks, and utility functions for safe data access and unique ID generation.

The primary responsibility of this hook is to encapsulate all logic related to handling the parameters (variables) of a node's form, thereby simplifying components that consume this data by abstracting the complex state update logic and event handlers.


Detailed Explanation

Imports


useHandleOperateParameters(nodeId: string)

Description

Custom React hook that manages the parameters (variables) of a node identified by nodeId. It provides handlers for adding, removing, changing, and saving parameters, exposing them alongside the current data source (list of parameters).

Parameters

Parameter

Type

Description

nodeId

string

Unique identifier of the node whose parameters are being managed.

Returns

An object containing:

Property

Type

Description

handleAdd

MouseEventHandler

Handler to add a new empty parameter variable.

handleRemove

(id?: string) => () => void

Handler to remove a parameter by its id.

handleComponentIdChange

(row: IInvokeVariable) => (value: string) => void

Handler to update the component_id field of a parameter.

handleValueChange

(row: IInvokeVariable) => ChangeEventHandler

Handler to update the value field of a parameter via input event.

handleSave

(row: IGenerateParameter) => void

Function to save all changes to a parameter object.

dataSource

IGenerateParameter[]

Current array of parameter variables for the node.


Internal Logic and Methods

1. Retrieving Node and Data Source

const { getNode, updateNodeForm } = useGraphStore((state) => state);
const node = getNode(nodeId);
const dataSource: IGenerateParameter[] = useMemo(
  () => get(node, 'data.form.variables', []) as IGenerateParameter[],
  [node],
);

2. changeValue

const changeValue = useCallback(
  (row: IInvokeVariable, field: string, value: string) => {
    const newData = [...dataSource];
    const index = newData.findIndex((item) => row.id === item.id);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      [field]: value,
    });

    updateNodeForm(nodeId, { variables: newData });
  },
  [dataSource, nodeId, updateNodeForm],
);

3. handleComponentIdChange

const handleComponentIdChange = useCallback(
  (row: IInvokeVariable) => (value: string) => {
    changeValue(row, 'component_id', value);
  },
  [changeValue],
);

4. handleValueChange

const handleValueChange = useCallback(
  (row: IInvokeVariable): ChangeEventHandler<HTMLInputElement> =>
    (e) => {
      changeValue(row, 'value', e.target.value);
    },
  [changeValue],
);

5. handleRemove

const handleRemove = useCallback(
  (id?: string) => () => {
    const newData = dataSource.filter((item) => item.id !== id);
    updateNodeForm(nodeId, { variables: newData });
  },
  [updateNodeForm, nodeId, dataSource],
);

6. handleAdd

const handleAdd: MouseEventHandler = useCallback(
  (e) => {
    e.preventDefault();
    e.stopPropagation();
    updateNodeForm(nodeId, {
      variables: [
        ...dataSource,
        {
          id: uuid(),
          key: '',
          component_id: undefined,
          value: '',
        },
      ],
    });
  },
  [dataSource, nodeId, updateNodeForm],
);

7. handleSave

const handleSave = (row: IGenerateParameter) => {
  const newData = [...dataSource];
  const index = newData.findIndex((item) => row.id === item.id);
  const item = newData[index];
  newData.splice(index, 1, {
    ...item,
    ...row,
  });

  updateNodeForm(nodeId, { variables: newData });
};

Usage Example

import React from 'react';
import { useHandleOperateParameters } from './hooks';
import { IGenerateParameter } from '../../interface';

interface Props {
  nodeId: string;
}

const ParameterEditor: React.FC<Props> = ({ nodeId }) => {
  const {
    dataSource,
    handleAdd,
    handleRemove,
    handleComponentIdChange,
    handleValueChange,
    handleSave,
  } = useHandleOperateParameters(nodeId);

  return (
    <div>
      <button onClick={handleAdd}>Add Parameter</button>
      {dataSource.map((param) => (
        <div key={param.id}>
          <input
            value={param.key}
            onChange={(e) =>
              handleSave({ ...param, key: e.target.value })
            }
          />
          <input
            value={param.value}
            onChange={handleValueChange(param)}
          />
          <button onClick={handleRemove(param.id)}>Remove</button>
        </div>
      ))}
    </div>
  );
};

Implementation Details and Algorithms


Interaction with Other System Parts


Mermaid Diagram

flowchart TD
  A[useHandleOperateParameters(nodeId)] --> B[getNode(nodeId)]
  B --> C[dataSource = node.data.form.variables]
  A --> D[changeValue(row, field, value)]
  D --> E[Clone dataSource]
  D --> F[Find index of row]
  D --> G[Update field in copied item]
  D --> H[updateNodeForm with new variables]

  A --> I[handleComponentIdChange(row)]
  I --> D

  A --> J[handleValueChange(row)]
  J --> D

  A --> K[handleRemove(id)]
  K --> L[Filter out param with id]
  K --> H

  A --> M[handleAdd(event)]
  M --> N[Prevent default and stop propagation]
  M --> O[Add new param with uuid]
  M --> H

  A --> P[handleSave(row)]
  P --> E
  P --> F
  P --> Q[Merge row fields into item]
  P --> H

Summary

The hooks.ts file encapsulates all logic for managing node parameters within a graph-based state system. By providing reusable, memoized handlers and exposing the current parameter list, it simplifies components that require parameter manipulation, while ensuring state updates are immutable and consistent. Its design follows React best practices and clean state management principles, making it an integral part of the node editing workflow in the larger application.