use-edit-query.ts
Overview
The use-edit-query.ts file defines a custom React hook named useEditQueryRecord designed to manage the editing lifecycle of query records within a form context. This hook integrates tightly with react-hook-form to manipulate an array of query inputs (BeginQuery objects), enabling functionalities such as adding, updating, deleting, and selecting query records. It also manages modal visibility states for editing records and tracks the currently selected record.
This hook abstracts complex form and UI state management related to query editing into a reusable logic piece, promoting cleaner component code and separation of concerns.
Detailed Explanation
useEditQueryRecord Hook
Signature
useEditQueryRecord({
form,
}: INextOperatorForm & { form: UseFormReturn }): {
ok: (record: BeginQuery) => void;
currentRecord: BeginQuery;
setRecord: (record: BeginQuery) => void;
visible: boolean;
hideModal: () => void;
showModal: (idx?: number, record?: BeginQuery) => void;
otherThanCurrentQuery: BeginQuery[];
handleDeleteRecord: (idx: number) => void;
}
Parameters
form: The form object returned byreact-hook-form'suseFormhook (UseFormReturn). This object handles form state and exposes methods such asgetValues,setValue, andcontrol.The hook also accepts
INextOperatorForminterface which may provide additional relevant properties, but in this code onlyformis explicitly destructured and used.
Returns
An object exposing the following properties and methods:
Name | Type | Description |
|---|---|---|
|
| Function to add a new query record or update an existing one in the inputs list. |
|
| The currently selected query record for editing. |
|
| Setter function to update the current selected record. |
|
| Boolean indicating if the modal for editing query records is visible. |
|
| Function to hide the modal. |
|
| Function to show the modal, optionally setting the index and current record being edited. |
|
| Array of query records excluding the one currently being edited (tracked by |
|
| Function to delete a query record at the specified index from the inputs list. |
Internal State and Hooks
useSetSelectedRecord<BeginQuery>()
Custom hook (imported) that provides state management for the currently selected record, returning:setRecord(record: BeginQuery)- update the current record.currentRecord- the currently selected record.
useSetModalState()
Custom hook (imported) managing modal visibility state:visible- boolean modal visibility.showModal()- to show the modal.hideModal()- to hide the modal.
useState(-1)
Local React stateindextracks the index of the currently edited query record within the inputs array. A value of-1means no record is selected (e.g., when adding a new record).useWatchfrom react-hook-form
Watches theinputsfield from the form to get real-time updates on the array of query records.useMemo
ComputesotherThanCurrentQuery— all input query records excluding the one currently edited, optimizing performance by recalculating only wheninputsorindexchanges.useCallback
Memoizes the handler functions to prevent unnecessary re-renders.
Functions and Methods
handleEditRecord(record: BeginQuery): void
Purpose:
Adds a new query record or updates an existing one in the form'sinputsarray.Parameters:
record- TheBeginQueryobject representing the query record to add or update.
Process:
Retrieves current
inputsfrom the form.If
indexis-1, appendsrecordto the end of the array.Otherwise, replaces the existing record at
indexwith the newrecordusingtoSpliced(a non-mutating splice).Updates the form's
inputsvalue with the new array.Hides the modal.
Example Usage:
handleEditRecord({
queryText: 'SELECT * FROM users',
id: 'query1',
// ...other BeginQuery properties
});
handleShowModal(idx?: number, record?: BeginQuery): void
Purpose:
Shows the modal for editing a query record, optionally setting the record and its index.Parameters:
idx(optional) - The index of the record in the inputs array to edit. Defaults to-1(no record selected).record(optional) - TheBeginQueryrecord to set as current.
Process:
Sets local
indexstate.Sets the current record via
setRecord.Shows the modal.
Example Usage:
handleShowModal(2, inputs[2]); // Edit the record at index 2
handleShowModal(); // Show modal for adding a new record
handleDeleteRecord(idx: number): void
Purpose:
Deletes a query record from the form's inputs array at the specified index.Parameters:
idx- The index of the record to delete.
Process:
Retrieves current
inputsfrom form.Filters out the record at
idx.Updates form's
inputsvalue.
Example Usage:
handleDeleteRecord(1); // Deletes the record at index 1
Implementation Details and Algorithms
Immutable Updates:
The hook uses immutable array operations to update theinputsarray in the form state, utilizingtoSplicedfor replacing elements andfilterfor deletion. This avoids side effects and plays well with React and react-hook-form.Modal and Record Selection Management:
The hook integrates with external custom hooks for modal visibility and selected record state, keeping concerns separated and reusable.Performance Optimization:
useMemois used to calculateotherThanCurrentQueryto avoid recalculating on unrelated renders.useCallbackmemoizes event handlers, optimizing React re-renders when passing these functions as props.
Form Interaction:
The hook tightly couples withreact-hook-formAPIs for watching and updating form fields, ensuring the UI remains in sync with form data.
Interaction with Other System Parts
Custom Hooks Integration:
useSetSelectedRecordmanages shared state of the selected query record across components or logic layers.useSetModalStatehandles modal visibility, likely shared with modal components.
Form Context:
This hook is designed to be used inside React components that manage a form viareact-hook-form. It expects the form object to be passed in and manipulates one of its fields (inputs).UI Components:
Components responsible for rendering the query inputs list, edit modal dialogs, and delete buttons will use this hook to get handlers and state, enabling a clean separation between logic and presentation.Data Model:
The hook operates onBeginQueryentities, which represent individual query records. The interfaceINextOperatorFormis related to the form structure but specifics are outside this file.
Usage Example
import React from 'react';
import { useForm } from 'react-hook-form';
import { useEditQueryRecord } from './use-edit-query';
import { BeginQuery } from '../../interface';
type FormValues = {
inputs: BeginQuery[];
};
const QueryEditorComponent = () => {
const form = useForm<FormValues>({ defaultValues: { inputs: [] } });
const {
ok: saveQuery,
currentRecord,
setRecord,
visible,
hideModal,
showModal,
otherThanCurrentQuery,
handleDeleteRecord,
} = useEditQueryRecord({ form });
return (
<>
<button onClick={() => showModal()}>Add Query</button>
{otherThanCurrentQuery.map((query, idx) => (
<div key={idx}>
<span>{query.queryText}</span>
<button onClick={() => showModal(idx, query)}>Edit</button>
<button onClick={() => handleDeleteRecord(idx)}>Delete</button>
</div>
))}
{visible && (
<Modal onClose={hideModal}>
<QueryForm
initialValues={currentRecord}
onSave={(updatedRecord) => saveQuery(updatedRecord)}
/>
</Modal>
)}
</>
);
};
Visual Diagram
flowchart TD
A[useEditQueryRecord Hook]
A --> B[useSetSelectedRecord<BeginQuery>]
A --> C[useSetModalState]
A --> D[useState(index)]
A --> E[useWatch(inputs)]
A --> F[useMemo(otherThanCurrentQuery)]
A --> G[handleEditRecord(record)]
A --> H[handleShowModal(idx?, record?)]
A --> I[handleDeleteRecord(idx)]
G --> E
G --> D
G --> C
H --> B
H --> D
H --> C
I --> E
I --> D
Summary
use-edit-query.ts provides a powerful and reusable hook to manage query record editing within a form, backed by robust state handling for modal visibility and selected records. It abstracts away complex form manipulation logic, providing clear APIs for components to integrate query editing features seamlessly.
This hook plays a critical role in systems dealing with dynamic query inputs, enabling add/edit/delete workflows with clean state management and UI feedback.