Giter VIP home page Giter VIP logo

react-use-form-state's People

Contributors

danielbuechele avatar dependabot[bot] avatar derrickbeining avatar dimaqq avatar fabianolothor avatar gcampes avatar gregfenton avatar gregleveque avatar jgierer12 avatar julesblm avatar jwalton avatar maygo avatar wouterraateland avatar wsmd avatar wswoodruff avatar xxczaki 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-use-form-state's Issues

useFormState API change suggestion

Currently the suggested use of this API is as follows:

  const [formState, { text, email, password, radio }] = useFormState();
  return (
    <form onSubmit={() => console.log(formState)}>
      <input {...text('name')} />
      <input {...email('email')} required />
      <input {...password('password')} required minLength="8" />
      <input {...radio('plan', 'free')} />
      <input {...radio('plan', 'premium')} />
    </form>
  );

What I don't like about this is the duplicated { text, email, password, radio } list. You have to repeat every input type you're using there. When you add or remove inputs in your form you possibly have to edit this list. I think adding or removing inputs should only involve adding/removing the <input> line.

To achieve that we can use the current API as follows:

  const [formState, inputs] = useFormState();
  return (
    <form onSubmit={() => console.log(formState)}>
      <input {...inputs.text('name')} />
      <input {...inputs.email('email')} required />
      <input {...inputs.password('password')} required minLength="8" />
      <input {...inputs.radio('plan', 'free')} />
      <input {...inputs.radio('plan', 'premium')} />
    </form>
  );

At this point, it seems to make sense to combine formState and inputs so that useFormState returns only one object:

  const form = useFormState();
  return (
    <form onSubmit={() => console.log(form.state)}>
      <input {...form.text('name')} />
      <input {...form.email('email')} required />
      <input {...form.password('password')} required minLength="8" />
      <input {...form.radio('plan', 'free')} />
      <input {...form.radio('plan', 'premium')} />
    </form>
  );

This also makes it clear which form each input belongs to, if you happen to have multiple forms within the same component.

I think this would be a nicer API. What do you think?

I know this would be a breaking change so I understand if you're not willing to implement this.

reset form

Hello!
Is there an easier way to cleanup the state? It would be good to have it specially when you submit the form.

useFormState should updated cache when onChange handler is changed

Here's an example of a component which lets you allocate an SMS number from Twilio. There's an "area code" field and a "country" field. When you change either of these, we send off a fetch call to twilio to get available phone numbers, and then when that call comes back with a list of numbers we set some call setPhoneNumbers to set the list of available phone numbers so you can pick one:

interface NumbersState {
    loading: boolean;
    numbers: apiV2.AvailableSms[] | undefined;
    loadId: number;
}

let nextLoadId = 0;

export function SmsPicker(props: {
    onChange: (value: string) => void;
    onBlur: (value: string) => void;
    value: string;
}) {
    const defaultNumbers = props.value ? [{ number: props.value }] : undefined;

    const [phoneNumbers, setPhoneNumbers] = React.useState<NumbersState>({
        loading: false,
        numbers: defaultNumbers,
        loadId: -1,
    });

    const fetchNumbers = (areaCode: string, country: string) => {
        // Every time we load, bump the `loadId`.  When we type "613" into
        // the area code box, we'll actually send a request for "6", then
        // another for "61" and finally a last one for "613".  When the
        // request for "6" comes back, we don't want to call
        // `setPhoneNumbers({ loading: false })`, because then while the
        // user is trying to pick a number, the list could change on them.
        // Instead, we want to keep showing a spinner until the "613" reply
        // comes in and just ignore the "stale" replies.

        const loadId = nextLoadId++;
        setPhoneNumbers({ loading: true, numbers: defaultNumbers, loadId });

        Promise.resolve()
            .then(async () => {
                // Not the real twilio API call.  :P
                const numbers = await twilio.getAvailableNumbers({
                    country,
                    areaCode,
                });

                if (phoneNumbers.loadId === loadId) {
                    setPhoneNumbers({
                        loading: false,
                        numbers: numbers.concat(defaultNumbers || []),
                        loadId,
                    });
                }
            })
            .catch(err => {
                // Blah blah blah
            });
    };

    const [formState, { text, raw }] = useFormState<{
        country: string;
        areaCode: string;
        selectedNumber: string;
    }>(
        {
            country: 'US',
            areaCode: '',
            selectedNumber: '',
        },
        {
            onChange(_e, oldValues, nextValues) {
                const { areaCode, country } = nextValues;
                if (areaCode !== oldValues.areaCode || country !== oldValues.country) {
                    fetchNumbers(areaCode, country);
                }
            },
        }
    );

    return (
        <section>
            <label>
                Country:
                <ReactSelect
                    options={COUNTRY_CODE_OPTIONS}
                    isMulti={false}
                    {...raw<string>({
                        name: 'country',
                        validate: value => value ? undefined : 'Required',
                    })}
                />
            </label>

            <label>
                Area Code:
                <input {...text('areaCode')} />
            </label>

            <label>
                SMS Number:
                {phoneNumbers.loading ? (
                    <Spinner />
                ) : phoneNumbers.numbers ? (
                    /* A phone number picker goes here - react-select or something... */
                ) : (
                    'Enter a Country and Area Code to search for a number'
                )}
            </label>
        </section>
    );
}

The problem is... this doesn't work. :(

The onChange option we pass into useFormState gets cached, so even though we pass a different onChange later, the new onChange gets ignored. onChange relies on fetchNumbers, which relies on phoneNumbers. This means every time we call into onChange, it calls the cached version with the cached fetchNumbers and the cached phoneNumbers, so every time fetchNumbers tries to do this bit:

if (phoneNumbers.loadId === loadId) {

phoneNumbers.loadId will always be -1.

We could improve on this by using useCallback() to make it so onChange and fetchNumbers only update when phoneNumbers changes, but if the onChange we pass into useFormState() changes, then useFormState() should probably use the new onChange handler instead of using the cached one.

Using with react-datepicker

There are components like react-datepicker where their onChange handler is not passing the event object as the first argument. For example, in ReactDatepicker's case, the onChange handler is something like: (Date, event) => void.

So when the form handler is trying to access the e.target.value, it's going to throw an error, because target is undefined.

Maybe the ability to override the onChange handler or to manually set a value would resolve this issue.

Is redux supported? How?

I'm trying to use this library in the following context:

  • there's a record that has many fields
  • I'm displaying a form with inputs for these fields
  • user would be editing some fields
  • async refresh process may change (other or same) field data

I wanted to get to the point where:

  • pristine fields would be updated only by async process
  • touched fields would be updated only by user

I figured I'd try redux, with data model like so:

// store state
{ record: {f1: "a", f2: "b", ...},
  overlay: {f2: "bbb", ...}}
// map-to-props
displayed = {...record, ...overlay}

At the moment I can't figure out how to marry react-use-form-state API to redux:

  • onChange is pre-field, and happens before state is changed
  • issuing redux action directly from formState gives me a react warning*

(*)

Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.

Am I missing something?
Is this library meant to keep data in component state only?

Question: access to formState in validate methods

Hi, I'm trying to validate two custom input fields for the start time and end time. The start time shouldn't be later than the end time and vice versa. When perform custom input validation, I can easily access the values of other input fields, but I cannot get information about their validation status.

This code gives the very first value of a formState object that's not updated:

function Form(eventData) {
  const [formState, { raw }] = useFormState({
    start: eventData.startTime,
    end: eventData.endTime,
  });
  return <>
    <TimePicker 
      {...raw({
        name: 'start',
        validate: (value, values) => {
          if (formState.validity.end !== false) { // <-- validity always undefined
            // ...
          } else {
            // ...
          }
        }
      )} 
    />
    {/* second TimePicker */}
  </>
}

It seems that the assigned validate function relies on closure from the first component render. Is there a workaround for getting the most recent formState object state? Thanks!

Can't set error from the onChange handler

I have a form onChange handler that sends the data to a backend. Based on that response, a field may become invalid.

Here is the sample code:

const saveFieldAsync = (name, value) => {
  const req = createRequest(name, value);
  axios(req).catch(e => {
    // I need to update the form state for the invalid field
  });
};

const [formState, formInputs] = useFormState(null, {
  onChange: ({ target: { name, value } }) => saveFieldAsync(name, value),
});

However, in order to do that I need the setFieldError passed to onChange. Technically, this is possible if you don't have a form-wide onChange but you attach manually an onChange handle for each input.

Here is the simplest solution I could come up with:
steliyan@f359f7b

I've tried making the formOptions to accept a function instead of an object, but the code got really ugly. You have a better understanding of the code, I'm pretty sure you can come with something better than me.

And last but not least, congrats on your work on this library! :)

Greetings, Steliyan.

[bug] useFormState callback cache causes stale closures

The implementation of useFormState is problematic because it caches callback functions passed to inputs.text et. al. This causes functions like onChange, validate, and onBlur to run with stale closures, namely, the closure with which they are initialised. This can be fixed simply by removing const callbacks = useCache(); from the implementation.

Custom Input Component

Suppose that I have a custom input component like TagSelector๏ผš

type TagSelectorProps = {
  values: string[]
  onChange: (values: string[]) => any
}

function TagSelector(props: TagSelectorProps) {}

And,

function MyForm() {
  // I think we should expose a 'onChange' method ๐Ÿ™‹โ€โ™‚๏ธ
  // So that we can call `onChange` manually
  const [formState, { onChange }] = useFormState({ tags: [] })

  return (
    <div>
      <TagSelector onChange={onChange} values={formState.values.tags} />
   </div>
  )
}

Setting state values manually

First of all, thanks a lot for this amazing work, @wsmd ! Huge time saver, very performant and extremely clean API, you really nailed it ๐Ÿ˜„

The only issue I have with this hook is the fact that you only pass down formState.current through the hook, meaning we're locked if we need to set state manually.

I'm creating a form in which I ask for an URL, fetch its meta title via a cloud function and then return it to automatically add it to the title input (which can also be edited by the user). I can run the fetchUrl through the onBlur option inside the URL input, but then I have no means of updating the title inside formState ๐Ÿ˜”

Is there any way we could return the whole formState object (in v.1) in the hook or is it too dangerous / wouldn't work? It'd be something like this:

// inside useFormState.js
return [
    formState,
    {
      ...inputPropsCreators,
      [LABEL]: (name, ownValue) => getIdProp('htmlFor', name, ownValue),
    },
  ];

// inside YourComponentForm.jsx
const [{ current, setValues }, input] = useFormState()

For the time being, I'll manage the title input outside of useFormState, unfortunately ๐Ÿ˜ญ

Make red on error

So, I wrote some code to make the label red whenever there is an error and the input has been touched:

    const redLabel = (...args) => {
        const field = args.slice(0, args.length - 1)
        const label_text = args[args.length - 1]
        return <label {...label(...field)}><span style={{color: formState.touched[field] && !formState.validity[field] ? 'red' : 'black'}}>{label_text}</span></label>
    }

Not sure if this is something that could be included in the project, but I thought it might be useful.

Here is the full code for context:

import { useFormState } from 'react-use-form-state'
import React from 'react'

export function Form() {
    const [formState, { label, text, email, password, radio }] = useFormState()
    const redLabel = (...args) => {
        const field = args.slice(0, args.length - 1)
        const label_text = args[args.length - 1]
        return <label {...label(...field)}><span style={{color: formState.touched[field] && !formState.validity[field] ? 'red' : 'black'}}>{label_text}</span></label>
    }

    return <form onSubmit={e => e.preventDefault() || console.log(formState)}>
        {redLabel('name', 'Full Name')}
        <input {...text('name')} />
        <br />

        {redLabel('email', "Email")}
        <input {...email('email')} />
        <br />

        {redLabel('password', 'Password')}
        <input {...password('password')} required minLength="8" />
        <br />

        Plan:
        <br />
        
        {redLabel('plan', 'free', 'Free Plan')}
        <input {...radio('plan', 'free')} />
        <br />
        {redLabel('plan', 'free', 'Premium Plan')}
        <input {...radio('plan', 'premium')} />
        <br />
        <button type="submit">Submit</button>
    </form>
}

Values for input.checkbox other than strings

Looks like the only accepted value types for input.checkbox is a string value. Is there a reason for this? Could it be possible to support other values like numbers, objects, or arrays? If not, then maybe it should be documented that value must be a string and to recommend serializing values into a string before hand.

[bug] validate called with undefined on blur for raw (and perhaps other) inputs

version 0.10.0

I believe I've encountered a bug and have opened a corresponding pull request with a potential solution (see #73).

Basically, for raw, I'm finding that my validate function is being invoked with undefined on blur, even when I set validateOnBlur to false, which is causing run-time errors.

So the problem appears to be two-fold.

  1. validate shouldn't be getting undefined passed to it
  2. validate shouldn't be called on blur when validateOnBlur is false (the default setting, I believe).

Please review my PR whenever you have a moment.

[feature request] Array field support

Let's say you have a field that is named: Requests:

type Requests = Array<{url: string, name: string}>

Is there a way to do something like this natively with the lib?

Of course, there are workarounds using 2 levels of formState:

  • Create one formState per row and add a global onChange listener to change the formState above
  • Use raw so you can trigger onChange manually for the above formState - this way you lose local validation

I feel the lib could support these cases natively

Thanks in advance

RFC: Add `id` to input props

First off, amazing work on this library, it has now fully replaced Formik for me!

Do you think it would be a good idea (perhaps with an opt-out option) to also set the input's id to the same value as name? I find myself constantly having to add the id in order to make it work with <label for="...">. On the other hand, setting it automatically may clash with other ids the developer wants to use throughout the page.

An alternative solution would be to generate a randomized id and expose it as part of the formState, or as a third top-level return value from useFormState().

If you think this would be a good addition I'd love to submit a PR for it.

Validate on submit

Thank for creating this fantastic library! I'd like to suggest adding the ability to trigger validation of the form. Specifically when a form is submitted you'd typically want to indicate to the user if he/she is missing some required fields (and maybe there's other stuff to be validated too). Currently if the user hasn't touched a field and tries to submit, that field won't be validated.

A simple and flexible solution would be to expose a method which could be called to trigger validation. Maybe that has some overlap with #52.

validity

Are you can explain better in docs how the validity works and how i can customize it?

Trigger all validation rules at once

Hi,

At this moment, user needs to visit a field at least once or that would not be reported as an error. How could i manually perform a validation on all fields before/after render?

My Bests,
Hung Tran

send InitialState in the input

Hi, I am using apollo-client and I don't know how to update the initialState of the hook when is inside the Query component, there is a way to do that?

...
const StartService: React.FunctionComponent<Props> = props => {
  const [formState, { text, select }] = useFormState();

  const withId = props.id;

  const result = {};

  return (
    <User>
      {({ data, loading }) => {
        const { me } = data || {};
        if (loading) return <Loading />;
        return (
          <Query
            query={GET_SERVICE_QUERY}
            variables={{ id: withId }}
            skip={!withId}
          >
            {({ data }) => {
              const { service } = data || {};
              if(service) {
                // Here I have the data to send to the initialState
              }
...

Btw I really like this project, very lightweight, thanks a lot!
A newbie

TypeError: raw is not a function

I am using a custom AutoComplete extending react-select like so:
const [formState, { raw, select }] = useFormState({ members: [] });

<AutoComplete ... {...raw({ name: 'members' })} />

And getting the following error:
Error: Uncaught TypeError: raw is not a function Script: http://localhost:3000/static/js/1.chunk.js, Line: 174414, Column: 5 TypeError: raw is not a function at AddToGroupForm (AddToGroupForm.jsx:84)

Is this perhaps user error? I'm trying to get this working with multiSelect - single select with my component and select works just fine, but I seem to need raw in order to capture the changes for multi.

Type definition of useFormState requires index signature

With the following:

interface ConnectFormState {
  user: string
  host: string
  password: string
  database: string
  port: number
}

const form = useFormState<ConnectFormState>()

I get:

TS2344: Type 'ConnectFormState' does not satisfy the constraint '{ [key: string]: string | number | string[]; }'.
  Index signature is missing in type 'ConnectFormState'.

I don't want to add an index signature to my form state.

Changing useFormState definition to the following seems to fix this:

export function useFormState<
  // old: T extends { [key: string]: string | string[] | number }
  T extends { [key in keyof T]: string | string[] | number }
>(

And it still disallows properties not of type string | string[] | number e.g. booleans.

Validate all inputs without touch

So imagine a scenario where a user clicks on the submit button without touching any of the fields, and since formState.validity object is empty, I am not able to verify the fields and also can't show the correct error message for each of them.

I think all of the fields should run the validation method on each render. There also could be a function to validate all the fields so we can use it in submissions.

Setup formState.validity onMount

Hi,

Love the lib. One enhancement I'd like to suggest if it is possible: it would be nice if there is a mount useEffect(()=>op(), []) that sets up the initial validity values from the HTML5 input.validity for each input('fieldName'). Currently validity values are set/updated when the user touches the input field.

For example, I have an Add/Edit dialog with a couple of required fields. On Add it is an empty initial state, on Edit the fields are pre-populated. I can't see if the formState is valid until the user clicks on each of the fields. I do not want to assume that if the formState.validity value is missing then it is not valid.

Would only work on formState.values.fieldName that have a corresponding input('fieldName'). For example, the Edit has a DB id I'd like to pass into the formState but not use in the form. I prefer not excluding in the initialState and then later add it back when I have to persist the change. So the on mount validity check would ignore this since there is no input('dbId').

Should work with & without a form tag.

Also maybe a formState.isValid boolean value or function that is true when all formState.validity values are true.

Form re-renders all of it's children even if the value hasn't changed

Hi there!

Great job with the lib, however I ran into something when implementing this.

The first this is that I am putting a console.log inside each form element to see how many times they re-render. And let's say I have a form like this:

  • checkbox 1
  • checkbox 2
  • radio 1
  • radio 2
  • radio 3

Every time I click a radio button, all of the elements, including the checkboxes will re-render. Even if I wrap them in React.memo. What's the reasoning behind this?

Can't find setFieldError method in formState

ver 0.10.4

hello, i had to set error at particular situation. so i read Doc and found setFieldError(setFieldError(name: string, error: string): void) Function.
but i couldn't find setFieldError method in the code

can you check for me? my version is resent

Improve types for BaseInputProps

The type definition for BaseInputProps types the name as string. However, we could type this more strictly: https://github.com/wsmd/react-use-form-state/blob/master/src/index.d.ts#L135

-interface BaseInputProps {
+interface BaseInputProps<T> {
  id: string;
  onChange(event: any): void;
  onBlur(event: any): void;
  value: string;
-  name: string;
+  name: keyof T;
  type: string;
}

I would create a PR, but the version published to NPM differs from the one here on GitHub, so I am not sure if all changes are yet pushed to GitHub

onSubmit check

Consider an email/password form. I type in the email, TAB, type in the password, ENTER.
We get this state from onSubmit callback:
submit
Which is logical since pressing ENTER doesn't trigger a blur event. Is it a good idea to let users implement this themselves instead of just being able to write:

  const hasClientErrors = !all(v => v === true, values(formState.validity))
  const onSubmit = () => {
    if (hasClientErrors) return
    onSubmit()
  }

EDIT: actually it's about using onKeyPress prop on controls so we can trigger validity check on ENTER. Maybe it would be nice to have it included with props builders <input {...email('email')} />

dynamically add fields

Is it possible to dynamically add fields? If so, would you happen to have an example? If not, it would be a cool enhancement.

type safety for Inputs?

on large forms, it's easy to mess up when dealing with strings that are namespaced (like address.street.lat), would be nice that the Inputs declaration had a generic Inputs<T> so it can accept the name as being part of the "keyof T" in useFormState, so [FormState<T>, Inputs] -> [FormState<T>, Inputs<T>]

Question/Suggestion: "touched" changes

I'd like a live comparison (as I type) of the formState to do things like enable/disable submit buttons, etc, without waiting for a blur event to trigger the actual formState.touched fields. Likewise, a global "isTouched", "isValid" (or similar), and such would be extremely handy - else this will be a super-common function that will need to be done each time.

I'd like to propose one of two options:

  • I submit a PR to the core project
  • I create an "extended" version that wraps your library, with a few quality-of-life adjustments such as those mentioned. It would match 1:1 your library signature, while either extending the formState object, or adding a 3rd extended array element in the return. This is obviously the easier one out of the gate for me, but more fragile, less easy to keep in sync with yours, etc.

That all said, I love what you've done, and the incredibly elegant interface it exposes!

something is broken ):

first of all, pretty impressive lib, i'm totally hooked (no pun intended) on the API you designed, it really seems flawless.

but i couldn't make it work:

  1. i'm on react and react-dom on v16.7.0-alpha.2
  2. i've tried with or without initial state object
  3. on the moment i add the declaration line, it crashes

do you have any idea of what this could be?

screen shot 2019-01-04 at 2 57 11 am

Request: include useEffect to reset (with new initial data) form on change of initialValue

Example

const MyComponent = () => {
  let [ item, setItem ] = useState({ foo: 'bar' })
  let [ formState ] = useFormState(item)

  setTimeout(() => {
   // this should trigger a component re-render 
   //which will fire a new "item"  value into the useFormState initialValue
   setItem({ fo: 'fum' }) 
  }, 2000)

  return (
    <pre>
     { 
       JSON.stringify(formState, null, 2)
       // this will continue to show the form state as originally 
       // set, instead of updating with new form data
     }
   </pre>
  )
}

Expected Behavior
When changing initialValue (e.g. as the product of another hook), I'd expect the form to reset itself (including untouched state) to the new base data.

Current Behavior
When changing initialValue from another hook, the form is left unchanged. This makes it difficult to dynamically load a form without using component hacks to force a re-instantiation of the useFormState hook

Workaround Hacks

  1. Throwing a useEffect into your component that watches for changes to [what should be] the form initialState, that manually does setFields based on the new object structure. Risks are that if the form structure changes at all, you may carry old data values along with the new (e.g. it may have old fields that were left in the form body because the new form state didn't have those attributes), as well the fact that they'll all be marked as touched instead of untouched.

Steps Forward

  • do not agree that changes to initialValue should be dynamically set form data
  • agree and will modify code to match
  • agree but would welcome a PR (I'd be happy to take a stab at it)

P.S. - @wsmd Love this library and the elegant interface - keep up the great work!

Supported number type for FormValue?

When my form values includes some number, the editor report 'type number is not assignable to string'. The code like this:

type FormValues = { status: number[] }
const [{ values }, { radio }] = useFormState<FormValues>({ status: [0, 1, 2, 3] }) // can not be assigned

The declaration file may not support the number type. Consider about supports, or any other solution?

npm update or install not updating

npm i -D react-use-form-state

results

+ [email protected]
updated 1 package and audited 37440 packages in 61.758s
found 63 low severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Not updating do v0.8.0.

[bug] setField() doesn't invoke formState's onChange() method

I try to update field manually and subscribe to onChange() method in formState object, but after I apply setField() the values of formState iteself is changing and onChange() doesn't executes

const [formState, { text, radio, label }] = useFormState<IProfilesFilter>(params, {
    onChange(
      event: React.ChangeEvent<InputElement>,
      old: StateValues<IProfilesFilter>,
      newValues: StateValues<IProfilesFilter>,
    ) {
      event.preventDefault();
      console.log(newValues);
    },
  });

  const handleSelect = (newValue: string): void => {
    formState.setField("selected", [...selectedItems, newValue]);
  };

label tag with problem

label tag is not running like expected.

// This code
<label {...label('name')}>Full Name</label>
<input {...text('name')} />

// Results
<label>Full Name</label>
<input name='name' type='text' value} />

// Expect
<label for='name'>Full Name</label>
<input name='name' type='text' value} />

About validate input validation function

validate(value: string, values: StateValues): boolean

Optional. An input validation function that gets passed the input value and all input values in the state. It's expected to return a boolean indicating whether the input's value is valid. HTML5 validation rules are ignored when this function is specified.

I was interested in this function as a way to determine the origin of the validation error. Right now with a boolean flag it's not possible to distinguish.

Maybe extend the validity shape like so:

"validity": {
    "name": {
         someValidationRule: true|false,
         otherValidationRule: true|false
    }
}

Thank you for the great lib :)

Reset form (not clear form)

Having a reset method which resets (not clears) everything including error, touched etc to the original values.

I pre-fill a form (settings) with values from the db using the default state. The user can change fields but also reset changes. The current clear method clears all the preset values instead of resetting to the original values.

The work around I'm using is to update the key to re-render the form but its a bit slow to re-render... e.g. from #33 https://codesandbox.io/s/x3kznwm6lo

Related to:
#33 (reset form)

Typescript parameter

First of all: Amazing, tiny lib! No dependencies, native typescript support, this is amazing. Thank you so much! So happy I don't need to code it myself xD ๐Ÿ™โค๏ธ

Small issue with typescript:

import React from 'react'
import { useFormState } from 'react-use-form-state'

type Form = {
	name: string
	password: string
}

const SomeForm: React.FC = () => {

	const [form, { text, password }] = useFormState<Form>()

	const _save = async () => {
		console.log(form)
	}

	return <div>
		<input {...text('name')} /> // This throws type error
		<input {...text({ name: 'name' })} /> // Ok
		<input {...password({ name: 'password' })} />
		<button onClick={_save}>Save</button>
	</div>
}

export default SomeForm

My tsconfig:

{
  "compilerOptions": {
    "target": "ESNEXT",
    "module": "commonjs",
    "jsx": "react",
     "removeComments": true,
    "noEmit": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "alwaysStrict": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Extend `FormOptions` to receive global `validateOnBlur` value

It'd be useful to set a global validateOnBlur method, validating on every input makes code a little noisy.

By the way, the real problem is that I am having some perf issues on a big form and adding validateOnBlur is making the form much lighter.

I can try to reprocude in a code sandbox and open another issue but nevertheless a global validateOnBlur would make sense for the lib I think

<select multiple> support

Either I'm missing the explanation on how to do this, but it seems as though it's currently not possible to create a select form element with a multiple attribute. Maybe an additional input.selectMultiple function should be added?

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.