vendredi 18 août 2023

React state management across functional components design pattern

I am working on a module that displays a list of records and allows the user to action a full create, read, update and delete on an individual record via a modal. To make the situation more complex the records have sub-records along with meta-data. A simplified example would be a recipes application.

We would have a top-level list of recipes displayed in a table including their name and ingredients. Users can click a single record to present the recipe in a modal with the table still visible in the background. From here they can unlock the modal to allow editing of the single record (ie; name, description, author) or update the list of ingredients individually via a nested table within view modal.

This module is built using the native state management with functional components split by logical action, ie; the list view and each CRUD modal state are separate. The ingredients are displayed in the view dialog but are rendered by their own functional component in a table. What is the recommended way to manage the states across these components?

At present the top-level list component holds all records in a single state with the below and the data being loaded in via a lazy load function:

const [recipes, setRecipes] = useState<IRecipe[]>();

As the table is built up via a map it passes each recipe through to the callback when displaying the modal, the modal component then initialises its own state for a single recipe with the value passed via the props.

const [recipe, setRecipe] = useState<IRecipe>(app);

Any actions taken against the recipe update the single recipe state within its context and similarly the recipe ingredients are passed down to their own functional component that hold them in their own IIngredients[] state.

This all works wonderfully for rendering the data however the concerns come around updating the root state upon close of the dialog as the top level table needs to display the new information. What is the optimal method for managing this to make sure the root list state is up to date and accurate?

The community seems divided on using the single top-level state throughout all modules or how this module is currently implemented. A single top-level state seems resource intensive and would involve lower modules performing logic beyond it's bounds however the alternative would be a lot of mirrored states being updated synchronously across multiple levels. I have also seen suggestions to use useReducer over useState but there are no clear design patterns leaning towards one or the other.

As a limitation, 3rd party state management like Redux is ruled out, the module is only to use native functionality.

Aucun commentaire:

Enregistrer un commentaire