Closed JamesPHoughton closed 1 month ago
Current Approach:
So far, we are handling the form management using the react hook useState() to manage state and side effects of various form inputs and selected options. For example, selectedOption, nameValue, durationValue, and elementValues (in AddPopup.tsx) are all state variables managed with useState.
Then, we use event handlers handleNameChange, handleDurationChange, handleSelectChange, and handleInputChange to handle user interactions with the form inputs. These functions update the corresponding state variables with the new values.
The handleSave function is used to handle form submission. It checks the saveType and performs the appropriate action such as adding a stage, editing a stage, adding an element, editing an element, deleting an element, or deleting a stage. After performing the action, it updates the treatment state and stores the updated treatment in local storage.
Lack of Form Validation: invalid data are currently allowed for example putting a string in the duration field
There is no error handling: For cases when the name is already taken or the duration is longer than the maximum
Different components can’t share the same form. In fact, the form state (e.g.nameValue, durationValue) is managed within the AddPopup component, and the form handling logic (e.g., handleNameChange, handleDurationChange) is also defined within this component. This means that if you wanted to use the same form in a different component, you would need to duplicate all of this state and logic in the other component. So we would end up with code duplication, lack of separation of concerns and reusability.
Other options: Higher level form libraries
Formik
It’s a popular library for building forms. It provides a “Formik” component that you can use to create your form. This component takes care of managing the form's state including the form values, the form submission, and form validation.
Handles form validation, submission and errors
With Formik, we can create a reusable form component that encapsulates the form state and handling logic. This component can then be used in multiple places in the project, without having to duplicate any code.
Can be used in combination with Zod for validation: we just need to create a schema for each form and if the inputs don’t match a schema then it raises an error → Zod is a JavaScript library for building schemas to validate data. It allows you to define the shape and content of your data using a simple and intuitive API. Zod schemas are used to validate data at runtime, and they can also generate TypeScript types based on the schema definition.You can then use Zod to define a validation schema for your form, and then use that schema with Formik's validationSchema prop. Formik will automatically validate your form values against the schema and set any validation errors.
React-Hook Forms
React Hook Form is a lightweight and efficient library for managing forms in React. It leverages React hooks and the HTML form validation API to provide a simple and intuitive API for form management.
This one uses useForm(): → useForm() creates an instance of a form which provides various methods and properties to manage the form like register (register input/select Ref and validation rules), handleSubmit (handles form submission) and errors ( object contains any validation errors for the form field).
Would work perfectly since we are using function components and not class components
Can also be used with Zod for more complex validation rules
Cons: The error messages provided by React Hook Form can sometimes be vague or difficult to understand, which can make debugging more challenging.
Looks like React-hook-forms is the way to go then! I've created an issue here: https://github.com/Watts-Lab/researcher-portal/issues/48 for the task of converting what we have to use that library. Would you like to fill out a description of the task to be done in the issue, and take a crack at it? The issue should probably start with a description of the high level goal, and end with a list of items that will help us know it's implemented correctly. I'll let you fill in the details, as practice using issues to document tasks. =)
Do you think this issue is ready to close, now that we've made the decision?
As a developer, I want to take advantage of other people's work to make forms easy, so that I don't have to write so much code, and i have more confidence that the code is robust.
The AddPopup.tsx file currently does a lot of manual work to make the form elements that get filled in. We can probably tighten this up (and improve form validation) using a form library. There are a number of different libraries we could choose: https://medium.com/@ansonch/5-best-libraries-to-develop-react-js-forms-2024-6a68f43c3187
My instinct at this point is to use something that interacts with our existing types and zod. From the perspective of brining on new people, it would make sense for it to be something popular, to increase the likelihood that our team has used it in the past, or that they can reuse their knowledge on other projects in the future.
Tasks