Skip to main content

side-drawer

The SideDrawer component is an alternative way for the user to update documents/rows.

Source Code: src/components/SideDrawer

3rd-party dependency: React Hook Form

Inside SideDrawer, we have the Form component, which uses React Hook Form to provide the hooks required to track the current row’s values, the user’s inputted values, and which fields the user has “dirtied” (interacted with and edited). React Hook Form allows us to build a form-like UI without relying on controlled components, so whenever a user types in a textbox, the entire form does not re-render.

How it works

For each field type, we provide a SideDrawerField component alongside the TableCell component. They use React Hook Form’s Controller to access the current row values and let the form component know when the user has input a value.

Form component

The Form component is rendered with a key, which is set to the currently selected row’s document path. Alongside Reset, this ensures the form always has the correct data for the currently selected row, and does not accidentally overwrite the newly-selected row with the previously-selected row’s data.

Autosave component

The Autosave component inside Form gets the latest value using useWatch and stores the fields (and values) that can be edited by the user in a state that’s debounced for 1 second.

A useEffect dependent on that debounced state then updates the values of cells that match the following criteria:

  1. The field must be dirty
  2. The user’s input value must be different from the current row value for that field

The effect then calls updateCell, which is the same function used by the Table component, on each field that needs to be updated. Usually, the effect only calls it once for one field at a time since the user does not update multiple fields fast enough.

Once the update is successful, the effect resets all dirty fields to prevent them being updated again in the future, in case the user updates a different field in the same row.

Reset component

The Reset component will resets the form’s values and errors whenever the row’s Firestore document’s data updates. For example, when another user updates the same row, this component will ensure the latest data is displayed in the SideDrawer.

This component does NOT reset any dirty fields, so a user will not lose any data they’ve input that has not been written to the database.

This component also does not reset if the current form’s values match the calculated new values, preventing any unnecessary resets in the case that the user has input data into a form field that has not been written to the database by Autosave.