使用钩子将React类组件重构为功能

时间:2020-06-30 10:49:02

标签: reactjs react-hooks

我正在重新审视3年前所做的项目。如果可能的话,我想将其重构为仅使用带有挂钩的功能组件。至少,我要摆脱现在不安全的生命周期方法,例如componentWillReceiveProps和componentWillMount。

下面的第一个代码是(在您看到的地方缩短了。)起点,第二个代码是我到目前为止的内容。我苦苦挣扎的一点是如何在没有componentWillReceiveProps的情况下访问nextProps?我知道一定要使用useEffect来解决问题,但是如何使用它却使我难以理解。有人能帮忙吗?如果有人能按照他们编写的方式显示代码,那么我的目标就太好了!如果您需要查看提到的任何其他代码,我将添加。谢谢。

起始代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference referralRef = rootRef.child("Balance").child("01555555125").child("referral");
referralRef.setValue(ServerValue.increment(20));

到目前为止我所拥有的:

class AddEducation extends Component {
  constructor(props) {
    super(props);
    this.state = {
      school: '',
      ..,
      errors: {},
      disabled: false,
    };

    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
    this.onCheck = this.onCheck.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.errors) {
      this.setState({ errors: nextProps.errors });
    }
  }

  onSubmit(e) {
    e.preventDefault();

    const eduData = {
      school: this.state.school,
      ..,
    };

    this.props.addEducation(eduData, this.props.history);
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }

  render() {
    const { errors } = this.state;

    return (
      <div className="add-education">
        ..
              <form onSubmit={this.onSubmit}>
                <TextFieldGroup
                  placeholder="* School"
                  name="school"
                  value={this.state.school}
                  onChange={this.onChange}
                  error={errors.school}
                />
                ..
              </form>
            ..
      </div>
    );
  }
}

AddEducation.propTypes = {
  addEducation: PropTypes.func.isRequired,
  profile: PropTypes.object.isRequired,
  errors: PropTypes.object.isRequired,
};

const mapStateToProps = (state) => ({
  profile: state.profile,
  errors: state.errors,
});

export default connect(mapStateToProps, { addEducation })(
  withRouter(AddEducation)
);

3 个答案:

答案 0 :(得分:2)

您可以使用useEffect作为依赖项之一来创建props钩子。

编辑:

useEffect(() => {
        if (props.errors) 
            setEduState({ errors: props.errors });
    },
    [props]
);

我相信您当前的useEffect会导致无限的重新渲染,因为您也将eduState和eduState始终设置为依赖项之一。

答案 1 :(得分:1)

更改

add_filter( 'woocommerce_get_country_locale', 'ireland_country_locale_change', 10, 1 );
function ireland_country_locale_change( $locale ) {
    $locale['IE']['postcode']['required'] = true;

    return $locale;
}

  setEduState({
      ...eduState,
      [e.target.name]: e.target.value,
    });

您已经覆盖了自己的状态,请不要这样做:D

答案 2 :(得分:1)

一些评论:

  1. 您应该避免将道具复制到该状态(请参见here)。您可以只使用道具中的errors

  2. 如果仍然需要复制它们,则可以利用以下事实:使用钩子时,您可以具有许多“状态”。在这种情况下,您可以将它们存储在称为errors的状态中:

    const [errors, setErrors] = useState()
    
  3. 您的效果应如下所示:

    useEffect(() => {
       setErrors(props.errors)
    }, [props.errors])