将componentWillReceiveProps重构为Hook

时间:2019-07-28 22:54:00

标签: javascript reactjs formik

我正在使用Formik效果库来控制我的onChange效果。但是,Formik效果库已损坏,因此我需要编写自己的效果来触发Formik from Temperature import Temperature from Fahrenheit import Fahrenheit from Celsius import Celsius from Kelvin import Kelvin prompt = "\nEnter a number for each temp, and I will give you all the info you need." prompt += "\n(Don't worry, we'll store all your info as we go along so you don't lose anything)" prompt += "\nYou can hit 'Enter' to add numbers or type 'quit' to stop the loop: " temperatures = [] while True: message = input(prompt) if message == 'quit': break else: print ("Enter a value for each temp, or enter 'quit' to finish") f = Fahrenheit(int(input('Enter a temp in F: '))) temperatures.append(f) c = Celsius (int(input('Enter a temp in C: '))) temperatures.append(c) k = Kelvin (int(input('Enter a temp in K: '))) temperatures.append(k) for temp in temperatures: print (temp.get_temp()) print (temp.above_freezing()) print (temp.convert_2F()) print (temp.convert_2C()) print (temp.convert_2K()) print () 函数。我为onChange()编写了一个class componentWillReceiveProps组件。但是,我所有的组件都是功能组件。我被要求将我的<Effect />组件重构为功能组件。我仍然是React的初学者,所以我在努力重构它。

这是我的课程class的组成部分

<Effect />

在我的心中,我回来了

// TODO: refactor with HOOK!

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'formik';

class Effect extends React.Component {
  componentWillReceiveProps(nextProps) {
    const { formik } = this.props;
    const { onChange } = this.props;
    const { values, touched, errors, isSubmitting } = formik;
    const {
      values: nextValues,
      touched: nextTouched,
      errors: nextErrors,
      isSubmitting: nextIsSubmitting
    } = nextProps.formik;
    if (nextProps.formik !== formik) {
      onChange(
        {
          values,
          touched,
          errors,
          isSubmitting
        },
        {
          values: nextValues,
          touched: nextTouched,
          errors: nextErrors,
          isSubmitting: nextIsSubmitting
        }
      );
    }
  }

  // eslint-disable-next-line
  render() {
    return null;
  }
}

Effect.defaultProps = {
  formik: {
    errors: {},
    touched: {},
    values: {},
    isSubmitting: false
  },
  onChange: () => {}
};

Effect.propTypes = {
  formik: PropTypes.shape({
    errors: PropTypes.shape({}),
    touched: PropTypes.shape({}),
    values: PropTypes.shape({}),
    isSubmitting: PropTypes.bool
  }),
  onChange: PropTypes.func
};

export default connect(Effect);

此效果的目的是在用户选择其他类型的表单时重置initialValue,因为initialValue仅呈现一次。并且当前的Formik库不支持onChange()函数。

<Effect onChange={(currentFormikState, nextFormikState) => { if ( currentFormikState && nextFormikState && currentFormikState.values.pdsaType !== nextFormikState.values.pdsaType ) { resetForm(initialValues[nextFormikState.values.type]); setType(nextFormikState.values.type); } }} /> 是Formik呈现的initialValue,currentFormikState是用户选择的nextFormikState值。

1 个答案:

答案 0 :(得分:0)

我不知道 formik ,但是我想从您的代码中您可以转换成这样的功能组件

import React, { useEffect, useRef } from "react";

function Effect(props) {
  const { formik, onChange } = props;
  const { values, touched, errors, isSubmitting } = formik;
  const formVariableRef = useRef();
  const formFormikRef = useRef();
  useEffect(() => {
    formFormikRef.current = formik;
    formVariableRef.current = { values, touched, errors, isSubmitting };
    if (formik !== formFormikRef) {
      onChange(
        {
          value: formVariableRef.current.values,
          touched: formVariableRef.current.touched,
          errors: formVariableRef.current.errors,
          isSubmitting: formVariableRef.current.isSubmitting
        },
        { values, touched, errors, isSubmitting }
      );
    }
    return function() {
      formFormikRef.current = formik;
      formVariableRef.current = { values, touched, errors, isSubmitting };
    };
  });
  return null
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

尝试用此替代您的班级形式。其余的可能不需要更改