简体   繁体   English

如何在 React 表单的构造函数中使用上下文?

[英]How can I use the context in the constructor in my React Form?

I have an issue in my React form.我的 React 表单有问题。 I must use the context to know what the name of the form is to set/get the value from the Redux store.我必须使用上下文来知道表单的名称是什么,以便从 Redux 存储中设置/获取值。

However, I have an issue.但是,我有一个问题。 My form is in two parts.我的表格分为两部分。 I set the values in the Redux store and if I need to go back to the previous part of the form, I still have the value saved.我在 Redux 存储中设置了值,如果我需要返回表单的前一部分,我仍然保存了该值。 However, I have a little problem.但是,我有一个小问题。 I can't set the default state of the form input using the context since I don't know how to access the context in the constructor.我无法使用上下文设置表单输入的默认状态,因为我不知道如何访问构造函数中的上下文。

Could you help me achieve this?你能帮我实现这个目标吗?

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
import { handleChange } from 'redux/actions';
import { connect } from 'react-redux';
import FormContext from 'context/FormContext';

export class TextInput extends Component {
  constructor (props, context) {
    super(props, context);
    this.state = { value: this.getValue(context) || '' };
    this.handleChange = this.handleChange.bind(this);
    this.handleBlur = this.handleBlur.bind(this);
  }

  getRequired () {
    if (this.props.required === true) {
      return <span className="tw-font-semibold tw-text-red-500 tw-text-sm tw-ml-2">{this.props.t('required')}</span>;
    }
  }

  handleChange (e) {
    var value = e.target.value;
    this.setState({ value: value });
  }

  handleBlur (context) {
    this.props.handleChange(this.props.name, this.state.value, context.name);
  }

  getValue (context) {
    if (this.props.input && this.props.input[context.name] && this.props.input[context.name][this.props.name]) {
      return this.props.input[context.name][this.props.name];
    } else {
      return undefined;
    }
  }

  render () {
    return (
      <FormContext.Consumer>
        {context =>
          <div className={`tw-flex tw-flex-col ${this.props.size} tw-px-2 tw-mb-3`}>
            <label htmlFor={this.props.name} className="tw-text-sm tw-font-bold">{this.props.title || this.props.t('common:' + this.props.name)}{this.getRequired()}</label>
            <input
              value={this.state.value}
              onChange={this.handleChange}
              onBlur={() => {
                this.handleBlur(context);
              }}
              type={this.props.type} id={this.props.name} placeholder={this.props.title} className="focus:tw-outline-none focus:tw-shadow-outline tw-bg-gray-300 tw-rounded-lg tw-py-2 tw-px-3" />
            {this.props.errors && this.props.errors[context.name] && this.props.errors[context.name][this.props.name] && (
              <div className="tw-bg-red-100 tw-mt-2 tw-border-l-4 tw-border-red-500 tw-text-red-700 tw-p-2 tw-text-sm">
                <p>{this.props.errors[context.name][this.props.name]}</p>
              </div>
            )}

          </div>
        }
      </FormContext.Consumer>

    );
  }
}

TextInput.defaultProps = {
  size: 'w-full',
  required: true,
  type: 'text'
};

TextInput.propTypes = {
  name: PropTypes.string.isRequired,
  title: PropTypes.string,
  size: PropTypes.string.isRequired,
  required: PropTypes.bool,
  type: PropTypes.string,
  t: PropTypes.func.isRequired
};

const mapStateToProps = ({ errors, input }, ownProps) => {
  return {
    errors: errors,
    input: input
  };
};

export default connect(mapStateToProps, { handleChange })(withTranslation(['input'])(TextInput));

How about you wrap your FormContext wherever you call your TextInput.在您调用 TextInput 的任何地方包装 FormContext 怎么样? In that way, you could access your FormContext in your constructor.这样,您就可以在构造函数中访问您的 FormContext。

function FormThatUsesTextInput() {
    return (
       <FormContext.Consumer>
          {context => <TextInput context={context} {...otherProps} />}
       </FormContext.Consumer>
    )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM