Giter Site home page Giter Site logo

core's Introduction

npm downloads npm npm Discord

Get started | API | Form Builder | FAQs | Examples

Features

Install

npm install react-hook-form

Quickstart

import { useForm } from 'react-hook-form';

function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <input {...register('firstName')} />
      <input {...register('lastName', { required: true })} />
      {errors.lastName && <p>Last name is required.</p>}
      <input {...register('age', { pattern: /\d+/ })} />
      {errors.age && <p>Please enter number for age.</p>}
      <input type="submit" />
    </form>
  );
}

Sponsors

Thanks go to these kind and lovely sponsors!

Past sponsors

Backers

Thanks go to all our backers! [Become a backer].

Contributors

Thanks go to these wonderful people! [Become a contributor].

core's People

Contributors

bluebill1049 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

sa02045

core's Issues

future development contributions

Summary

I'd like to contribute to the development of hook-form's framework agnostic core as well as framework specific adapters.

To accomplish this, I've implemented a framework-agnostic interpretation of react-hook-form with a react adapter that passes all of the tests in the main react-hook-form library.

My work and proof of concept can be found here: https://github.com/ap0nia/forms.js

There is no documentation other than the tests that I've ported over at this time, but I can definitely add anything as needed!

Project Information

I've co-located three packages within the repository.

  • common: An internal package with runtime utility functions that correlate to react-hook-form's utils folder.
  • core: The agnostic library that exposes two main class-based interfaces for controlling forms
    • form-control: A class that manages data for an entire form.
    • field-array: A class that accepts a control in order to abstract operations with field arrays on the form control.
  • react: React bindings for the core library.

Key Files

Status

I've passed all of the tests from react-hook-form and I think it's a solid proof of concept for the core library. I don't intend the react bindings to replace the existing library; I just created them as a baseline for future adapters and to enable me to test the core class functionality.

Next Steps

I'd like to know if there's anything I can do with this work. e.g. Should I open a PR to get things started? My code was written from scratch so there's no base to merge from ๐Ÿค”

Implementation

Here is a mini-blog post about implementation details. It would be great to have a formal discussion about preparing the project for future development!

Classes

I used a class based approach since it was a lot simpler to model state mutations. One downside is that methods are not auto-bound to their instances, however this is actually a work around for this by using the arrow function syntax, so it's feasible to write the core API as a class, but retain the properties of an object.

Functions/Methods

I tried to use the original method names wherever possible, and I took liberty of adding/removing layers of abstraction to aid the (subjective) readability of the code. This can definitely be refactored as needed and I hope it doesn't detract from the legitimacy of the proof of concept.

Observable

I applied the general idea of writable stores, i.e. the same ones as Svelte, to represent every individual state value. It's possible to subscribe to each one individually. However, React and react-hook-form want to optimize number of render counts by ###batching### updates wherever possible, so I engineered my solution around a batchable observable that can subscribe to multiple stores and only update on certain events.

Batchable

The batchable requires an object that maps keys to observables. For example:

const myWritableMapping = {
  isDirty: new Writable(false),
  isValid: new Writable(false)
}

Here, the keys isDirty and isValid are mapped to an observable (writable). The batchable subscribes to both stores, and when either
of them change, the batchable will update itself and notify its own subscribers. i.e. A consumer will subscribe to the batchable, and the batchable will subscribe to all the stores.

Tracking

However, the batchable will only notify for updates with valid combinations of key and context.

  • Key a key just represents a key in the mapping, for instance "isDirty" and "isValid" are valid string keys to access the object mapping above.
  • Context a context is an accompanying value, usually a string or string array, that can fine-tune the update.

Practical Example of Tracking

const writables = {
  values: new Writable({})
}

const batchable = new Batchable(writables)

batchable.track('values', 'username')

batchable.subscribe(console.log)

// NO console.log, since this didn't include the correct context, i.e. "username"
writables.values.set({})

// YES console.log, this was a change specifically triggered by "username"
writables.values.set({}, 'username')

You want to subscribe to updates to values but only when username triggered the change.

Batching
Finally, to quickly summarize batching, the combinations of changes triggered, e.g. ["values", "username"] might indicate that the store at the "values" key was changed with the "username" context, are stored in a buffer. When the batchable is flushed, all the combinations are parsed, and if any of them are being tracked, then a notification is triggered. Otherwise the batchable is already up to date, but does not send any notifications (and thus doesn't trigger any re-renders).

batchable vs. react-hook-form subjects

React-hook-form manually performs a comparison of the current formState and the next formState, evaluates which keys have changed, etc. whenever deciding whether to render. Although there's definitely a lot of room for refinement, I created the batchable + observable pattern as an alternative where you could 1) cork the batchable, 2) perform any updates needed on any number of observables, 3) flush the batchable and send a single notification if needed.

And this system would hopefully be sophisticated enough where if you followed its documented procedures and understood its behavior well, you wouldn't need to do manual confirmations for each render.

Also because all updates are proxied through this single location, it may be possible to implement additional dev tools that visualize the flow of data in/out of the batchable interface, in addition to building more robust flows like flux on top of it if needed.

development of hookform/core for alternative frameworks

Is your feature request related to a problem? Please describe.

I'd like a Svelte implementation of react-hook-form. I'd like to expose corresponding register hooks that can automatically bind an input element to a store and automatically track changes while optimizing updates.

Describe the solution you'd like

There's an existing implementation of a framework agnostic core library that I'd like to extend. I'd like to use it to build out a proof of concept for Svelte.

I've implemented a version of @hookform/core from the ground up with vanilla JS in mind. Using this core, I built @hookform/react and passed all of the related tests from react-hook-form. My work can be found here: https://github.com/ap0nia/forms.js/tree/main/packages/react

Describe alternatives you've considered

I'm not a big fan of existing solutions for Svelte because it's either type-unsafe or heavily relies on two-way data binding, which is too opaque for my needs.

Additional context

This issue is forwarded from an issue I made at the core library because I'm not sure how visible it is there.

I think a possible point of difficult is divergence of the hookform/core library and its dependents from the main react-hook-form library, since I wrote everything from scratch to emulate the same external behavior, but not necessarily the internals. I'm willing handle the maintenance burden if it enables hookform to be applicable more widely.

I was just really interested in hearing thoughts about this topic, thanks!

Broken Validation when using React Elements for Messages

Version Number

7.43.2

Codesandbox/Expo snack

n/a

Steps to reproduce

hello react-hook-form folks!

28cafa864b4a92b2d2f6ac8f5c5cb27722e38b3f removed the option to use react elements as validation messages. as a result internationalization libraries that use elements for translation of validation messages no longer work.

For example, with react-intl/formatjs:

<input type="text" {...form.register("name", { required: <FormattedMessage defaultMessage="this is required" /> })} />

most internationalization libraries (including formatjs) can produce strings but the element api is often more convenient, can use constant values, and doesn't require boilerplate to get things out of context

Expected behaviour

hopefully we can bring this back.

What browsers are you seeing the problem on?

No response

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.