Building a Commit Phase in a React Form
This challenge focuses on implementing the "commit" phase of a form in a React application. Often, after a user fills out a form, you need to gather all the data, perform final validations, and then send it to an API or perform some other action. This challenge asks you to build a reusable component that handles this commit process, including displaying loading states and error messages.
Problem Description
You are tasked with creating a CommitButton component that encapsulates the logic for committing form data. This component will be used within a larger form component. The CommitButton should:
- Accept a
commitFunctionprop: This function is responsible for handling the actual submission of the form data. It should accept the form data as an argument. - Accept a
loadingprop: A boolean value indicating whether the commit process is currently in progress. - Accept a
errorMessageprop: A string containing an error message to display if the commit fails. - Disable itself when
loadingis true: Prevent multiple submissions while the commit is in progress. - Display appropriate states:
- When
loadingis false anderrorMessageis empty, display a standard "Commit" button. - When
loadingis true, display a loading indicator (e.g., a spinner). - When
loadingis false anderrorMessageis not empty, display the error message.
- When
- Call the
commitFunctionwhen clicked: When the button is clicked (and not disabled), call the providedcommitFunctionwith the form data (assume the form data is available globally or passed as a prop to the parent component). For simplicity, you don't need to manage the form data itself within this component.
Examples
Example 1:
Input: commitFunction: (data: any) => console.log("Commiting:", data), loading: false, errorMessage: ""
Output: <button>Commit</button>
Explanation: The button displays the default "Commit" text.
Example 2:
Input: commitFunction: (data: any) => console.log("Commiting:", data), loading: true, errorMessage: ""
Output: <div className="loading">Loading...</div>
Explanation: A loading indicator is displayed.
Example 3:
Input: commitFunction: (data: any) => console.log("Commiting:", data), loading: false, errorMessage: "Submission failed. Please try again."
Output: <div className="error">Submission failed. Please try again.</div>
Explanation: An error message is displayed.
Constraints
- The component should be written in TypeScript.
- The
CommitButtoncomponent should be reusable and not tightly coupled to any specific form. - The
commitFunctionis assumed to be asynchronous and may throw an error. - You are free to use any styling approach (CSS, styled-components, etc.). Focus on the logic.
- Assume the parent component will manage the form data and pass it to the
commitFunction.
Notes
- Consider using React's
useStatehook to manage the local state of the component (e.g., to track loading and error states if they aren't managed externally). - Think about how to handle potential errors thrown by the
commitFunction. - The loading indicator and error message styling are left to your discretion. Focus on the core logic of displaying the correct state based on the props.
- This component is designed to be a building block. It doesn't handle form validation itself; it assumes the data is already validated before being passed to the
commitFunction.