#javascript #reactjs #redux
#javascript #reactjs #сокращение
Вопрос:
У меня проблема в моей форме реагирования. Я должен использовать контекст, чтобы узнать, каково имя формы, чтобы установить / получить значение из хранилища Redux.
Однако у меня есть проблема. Моя форма состоит из двух частей. Я устанавливаю значения в хранилище Redux, и если мне нужно вернуться к предыдущей части формы, у меня все еще сохраняется значение. Однако у меня есть небольшая проблема. Я не могу установить состояние формы ввода по умолчанию с использованием контекста, поскольку я не знаю, как получить доступ к контексту в конструкторе.
Не могли бы вы помочь мне достичь этого?
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 amp;amp; this.props.input[context.name] amp;amp; 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 amp;amp; this.props.errors[context.name] amp;amp; this.props.errors[context.name][this.props.name] amp;amp; (
<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));
Ответ №1:
Как насчет того, чтобы обернуть ваш FormContext везде, где вы вызываете свой TextInput. Таким образом, вы могли бы получить доступ к вашему FormContext в вашем конструкторе.
function FormThatUsesTextInput() {
return (
<FormContext.Consumer>
{context => <TextInput context={context} {...otherProps} />}
</FormContext.Consumer>
)
}