Hone logo
Hone
Problems

Building a useFormContext Hook for React Form Management

Creating a reusable useFormContext hook is a common pattern in React applications that manage complex forms. This hook allows child components to easily access and update form values and other form-related state without prop drilling. This challenge will guide you through building this hook, enabling cleaner and more maintainable form components.

Problem Description

You are tasked with creating a useFormContext hook in TypeScript that provides access to a form context. The context will hold the following:

  • values: An object representing the current form values. The keys of this object will be the names of the form fields, and the values will be the corresponding input values.
  • onChange: A function that accepts an event object and updates the form values.
  • reset: A function that resets the form values to their initial state (an empty object).

The hook should:

  1. Consume the form context.
  2. Return an object containing the values, onChange, and reset properties.
  3. Handle the case where the component is not within a FormProvider (the context provider). In this scenario, it should return a default object with empty values and placeholder functions.

Expected Behavior:

When a component uses useFormContext, it should receive the current form state and functions to modify it. The onChange function should be called whenever an input field's value changes, and the reset function should clear all form values. If the component is not wrapped in a FormProvider, it should gracefully handle this by returning default values.

Edge Cases to Consider:

  • What happens if the component is used outside of a FormProvider?
  • How should the onChange function handle different input types (e.g., text, select, checkbox)? (Assume the event object is standard for all input types).
  • How to handle initial form values? (Assume initial values are managed by the FormProvider and not part of this hook's responsibility).

Examples

Example 1:

Input: A component using useFormContext within a FormProvider with initial values { name: "John", email: "john@example.com" } and an onChange handler that updates the context.
Output: The component receives an object with values { name: "John", email: "john@example.com" }, an onChange function, and a reset function.  When the 'email' input changes to "newemail@example.com", the component's values update to { name: "John", email: "newemail@example.com" }.
Explanation: The hook successfully consumes the context and provides the current form state and update functions.

Example 2:

Input: A component using useFormContext outside of a FormProvider.
Output: The component receives an object with values {}, an onChange function that does nothing, and a reset function that does nothing.
Explanation: The hook gracefully handles the case where it's not within a context provider by returning default values.

Example 3:

Input: A component using useFormContext within a FormProvider. The user calls the reset function.
Output: The component receives an object with values {}, an onChange function, and a reset function.
Explanation: The reset function clears all form values as expected.

Constraints

  • The hook must be written in TypeScript.
  • The hook must consume a React Context.
  • The onChange function should accept a standard React event object.
  • The reset function should clear all form values.
  • The solution should be concise and readable.
  • The hook should not modify the context directly; it should only consume it.

Notes

  • You'll need to create a FormProvider component to provide the context. While you don't need to implement the entire FormProvider, you should assume its existence and that it provides the necessary context value.
  • Consider using React's useContext hook to consume the context.
  • Think about how to handle the case where the context is not provided. Returning default values is a good approach.
  • Focus on the logic of the useFormContext hook itself. The FormProvider is assumed to be already implemented.
  • The initial form values are managed by the FormProvider and are not the responsibility of this hook.
Loading editor...
typescript