jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
34.01k stars 2.79k forks source link

Formik Validation passed to object. #1805

Open michaelcuneo opened 5 years ago

michaelcuneo commented 5 years ago

I have a Formik form validation working fine with my form, but one of the areas of the form is actually an imported Class component containing a huge editor that I wrote with React Slate. I'd like some validation on the React-Slate component, but passing onChange, onBlur through as Props don't appear to affect the Formik wrap. Is there a better way to do this?

<Formik
  initialValues={this.state.values}
  validationSchema={bioAdminValidation}
  onSubmit={(values, { setSubmitting }) => {
    this.props.onChangeFormData(values);
    this.props.onSaveBio(this.state.file);
    setSubmitting(false);
  }}
>
   {({
    dirty,
    values,
    errors,
    touched,
    handleChange,
    handleBlur,
    handleReset,
    handleSubmit,
    isSubmitting,
  }) => (
    <form onSubmit={handleSubmit}>

...
my entire form
... 

    <EditorContainer
      id="bio"
      target="bio"
      mode={this.props.mode}
      value={values.bio}
      onChange={handleChange}
      onBlur={handleBlur}
    />

...
rest of form with reset and submit buttons.
...

      </form>
    )}
  </Formik>

Obviously the editor container never changes because it's not a form component that handles onChange or onBlur, because I wrote it... but if I add them to the EditorContainer component, it still won't change anything.

johnrom commented 5 years ago

It seems like React Slate accepts onChange, value, and onBlur. You can pass Formik's props all the way down to there. Of course, the onChange and onBlur that React Slate accepts are probably different than what Formik accepts, so you may need to do some mapping, like:

<SlateComponent onChange={change => { formik.onChange(fieldProps.name)(change.value) }} />

You'll have to read the docs through Slate, but it looks like you should have no problem using Formik's persistent state within it per the docs.

https://docs.slatejs.org/slate-react/editor#onchange

michaelcuneo commented 5 years ago

Ahh yes. I'll have a look the mapping. I think mapping might be what I was missing. Thanks.

johnrom commented 5 years ago

Awesome, let me know if it works well and I can close this issue!

michaelcuneo commented 5 years ago

My editorcontainer is actually an { Editor } from 'react-slate' ... I have tried all manner of mappings, but it doesn't seem to be getting through... If I could see the state of handleChange, that would be handy.

johnrom commented 5 years ago

@michaelcuneo why don't you create a codesandbox and try implementing it there? you should be able to add a dependency to react-slate and produce a bare minimum field editor there. Once you've hit a wall, send a link in a comment and I'll see if I can help with it.

michaelcuneo commented 5 years ago

My project might be too complex for a sandbox, but i'll see if I can push it through.

kennethacohen commented 4 years ago

@michaelcuneo any chance you were able to figure anything out here? Think I'm running into the same issue..

ghost commented 4 years ago

I think I've faced the same issue. My workaround is to invoke formik's onChange after slate's onBlur is triggered like:

const TextEditor = (props) => {
      ...
      const onBlur = (onBlurEvent) => {
        props.onBlur(props.name)(onBlurEvent);
        props.onChange(props.name)(serializedValue);
      }
      return (
        <Slate editor={editor} value={value} onChange={value => setValue(value)} >
          <Editable onBlur={onBlur}/>
        </Slate>
      );
}

// TextEditor is used like:
<Field name='text' placeholder="Content" as={TextEditor}/>