How to execute custom function once the field is valid with Formikl / Yup

无人久伴 提交于 2019-12-11 15:42:14

问题


I want execute a custom function when the field become valid?

Something like this..
<Field name="postal-code" onValid={...} />

The reason is that I want make fetch (GET) to get address from API once the user type an valid Postal code


回答1:


You can define the custom function inside the component class or outside the component.

// outside the component (best suited for functional component)
const onValidFn = () => {
 // perform action
}
// inside the component (best suited for stateful component)
onValidFn() {
 // perform action
}

If you want to access this inside the onValidFn method, you may bind this inside the constructor or use public class method:

onValidFn = () => {
  // perform action
  console.log(this)
}

// if your method is defined in outer scope
<Field name="postal-code" onValid={onValidFn} />

// if your method is defined in inner scope (inside class)
<Field name="postal-code" onValid={this.onValidFn} />



回答2:


You can solve it like this:

  • have Loader component which loads data if it gets an URL
  • pass URL to this component if touched[fieldName] && !errors[fieldName]

Loader component can be like

import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import superagent from 'superagent'; // swap to your xhr library of choice

class Loader extends PureComponent {
  static propTypes = {
    url: PropTypes.string,
    onLoad: PropTypes.func,
    onError: PropTypes.func
  }

  static defaultProps = {
    url: '',
    onLoad: _ => {},
    onError: err => console.log(err)
  }

  state = {
    loading: false,
    data: null
  }

  componentDidMount() {
    this._isMounted = true;
    if (this.props.url) {
      this.getData()
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.url !== this.props.url) {
      this.getData(nextProps)
    }
  }

  componentWillUnmount() {
    this._isMounted = false
  }

  getData = (props = this.props) => {
    const { url, onLoad, onError } = props;

    if (!url) {
      return
    }

    this.setState({ data: null, loading: true });

    const request = this.currentRequest = superagent.
      get(url).
      then(({ body: data }) => {
        if (this._isMounted && request === this.currentRequest) {
          this.setState({ data, loading: false }, _ => onLoad({ data }));
        }
      }).
      catch(err => {
        if (this._isMounted && request === this.currentRequest) {
          this.setState({ loading: false });
        }
        onError(err);
      });
  }

  render() {
    const { children } = this.props;
    return children instanceof Function ?
      children(this.state) :
      children || null;
  }
}

If no url is passed, it does nothing. When url changes - it loads data.

Usage in Formik render/children prop:

<Loader
  {...(touched[fieldName] && !errors[fieldName] && { url: URL_TO_FETCH })}
  onLoad={data => ...save data somewhere, etc.}
/>


来源:https://stackoverflow.com/questions/52122046/how-to-execute-custom-function-once-the-field-is-valid-with-formikl-yup

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!