Formik: Custom onChange with callback to Formik parent

Created on 5 Dec 2018  路  2Comments  路  Source: formium/formik

Hey folks,

I have got a Formik component with several subcomponents wich render input fields. On changing a specific value in one of the subcomponents, I would like to make a callback in the parent to render another subcomponent.

FormikMainComponent

class FormikMainComponent extends React.Component {
 constructor(props) {
    super(props);
    this.state = {
      shouldRenderSubcomponent: false
    };
  }

 handleChangeInSubcomponent = value => {
 this.setState({
      shouldRenderSubcomponent: value
    });
  };

  render() {
    const { classes } = this.props;
    return (
      <Formik
        initialValues={this.initialValues()}
        validationSchema={StandardSchema}
        onSubmit={values => this.handleSubmit(values)}
      >
        {props => {
          return (
              <Form className={classes.form}>
                     <SubComponent handleChangeInSubcomponent={handleChangeInSubcomponent } />
                      { this.state shouldRenderSubcomponent && <OtherSubcomponentWithInputs /> }
              </Form>
          );
        }}
      </Formik>
    );
};

SubComponent

const SubComponent = props => {
    return (
    <Field
         name="field1"
         id="field1"
         component={CustomSwitch}
         onChange={e => {
            this.props.handleChangeInSubcomponent (e.target.value);
            this.setFieldValue('field1', e.target.value);
         }}
     />
    );
};

Actually, I am not sure whether I can call setFieldValue here at all. Is is possible what I am trying to archive? Some thread on Stackoverflow proposed to use the subcomponent's state to make the input field controlled.
Can someone help me?

Question

Most helpful comment

Hi Jared,

thank you. I got it working by myself. It had tried the working solution before, but somehow it did not work. But now I do understand that I can simply check the values if I use a instead of in the Subcomponent

 <Formik
      initialValues={{ someValue : 'jared' }}
      onSubmit={...}
      render={props => (
        <form onSubmit={props.handleSubmit}>
          ...
            props.values.someValue =='whatever' && <SomeComponent />
          ...
        </form>
      )}
    />

But I have got another question regarding in Subcomponent.
If I want to call setFieldValue in a Subcomponent, I always will have to pass down the Formik props (or at least the function) to the component, won't I?

There is no other way to access the Fomik helper functions further down the tree, isn't it?

_MainFormikComponent_

 <Formik
      initialValues={{ someValue : 'jared' }}
      onSubmit={...}
      render={props => (
        <form onSubmit={props.handleSubmit}>
          ...
            <SomeComponent setFieldValue={props.setFieldValue}/>
          ...
        </form>
      )}
    />

_FormikSubComponent_

const MemberEditBase = props => {
  const { classes, setFieldValue} = props;

  return (
     <Field
        name="someField"
        onChange={e => {
           customStuff;
           setFieldValue('someField', e.target.value);
        }}
       ...
      />
  )
}

All 2 comments

You'll want to use a child component. If you hop on Discord, someone can walk you through how to do this.

Hi Jared,

thank you. I got it working by myself. It had tried the working solution before, but somehow it did not work. But now I do understand that I can simply check the values if I use a instead of in the Subcomponent

 <Formik
      initialValues={{ someValue : 'jared' }}
      onSubmit={...}
      render={props => (
        <form onSubmit={props.handleSubmit}>
          ...
            props.values.someValue =='whatever' && <SomeComponent />
          ...
        </form>
      )}
    />

But I have got another question regarding in Subcomponent.
If I want to call setFieldValue in a Subcomponent, I always will have to pass down the Formik props (or at least the function) to the component, won't I?

There is no other way to access the Fomik helper functions further down the tree, isn't it?

_MainFormikComponent_

 <Formik
      initialValues={{ someValue : 'jared' }}
      onSubmit={...}
      render={props => (
        <form onSubmit={props.handleSubmit}>
          ...
            <SomeComponent setFieldValue={props.setFieldValue}/>
          ...
        </form>
      )}
    />

_FormikSubComponent_

const MemberEditBase = props => {
  const { classes, setFieldValue} = props;

  return (
     <Field
        name="someField"
        onChange={e => {
           customStuff;
           setFieldValue('someField', e.target.value);
        }}
       ...
      />
  )
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

pmonty picture pmonty  路  3Comments

emartini picture emartini  路  3Comments

Jucesr picture Jucesr  路  3Comments

outaTiME picture outaTiME  路  3Comments

jaredpalmer picture jaredpalmer  路  3Comments