我正在使用手动制作的表单生成器并使用React Final Form来管理状态和数据。现在的问题是,我需要从表单外部的组件读取数据,甚至在提交之前向用户显示输入的实际状态。
import React, { Component } from 'react'
import PropTypes from 'prop-types';
import { I18n } from 'react-i18nify';
import * as INPUTTYPES from '../../constants/inputTypes';
import { CONCAT_ID_BASES } from '../../constants/config';
import 'babel-polyfill';
import { Form, Field } from 'react-final-form'
const weblog = require('webpack-log');
const log = weblog({ name: 'wds' }) // webpack-dev-server
class FormGenerator extends Component {
static propTypes = {
fields: PropTypes.any,
prefix: PropTypes.any,
children: PropTypes.any
}
state = {
data: {}
}
sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
onSubmit = async values => {
await this.sleep(300)
window.alert(JSON.stringify(values, 0, 2))
}
static simpleMemoize = fn => {
let lastArg
let lastResult
return arg => {
if (arg !== lastArg) {
lastArg = arg
lastResult = fn(arg)
}
return lastResult
}
}
static textValidate = FormGenerator.simpleMemoize(async value => {
if (!value) {
return I18n.t('error-no-text-written');
}
//await sleep(400)
if (value.trim().length() > 0) {
return I18n.t('error-no-text-found');
}
})
static createInput = (newKey, value, validate) => {
let data = {
type: value.type,
//disabled: typeof value.editable !== "undefined" ? !value.editable : false,
className: "form-control",
id: `${newKey}`,
value: value.value
}
return <Field key={newKey} name={data.id} validate={validate}>
{({ input, meta }) => (
<div className="form-group col-md-6">
<label htmlFor={`${newKey}`}>{I18n.t(`${newKey}`)}</label>
<input {...data} {...input} />
{meta.error && meta.touched && <span>{meta.error}</span>}
</div>
)}
</Field>
}
static createSelectInput = (newKey, value) => {
let data = {
type: value.type,
disabled: typeof value.editable !== "undefined" ? !value.editable : false,
className: "form-control",
id: `${newKey}`,
value: value.value
}
return <React.Fragment key={newKey}>
<div className="form-group col-md-6">
<label htmlFor={`${newKey}`}>{I18n.t(`${newKey}`)}</label>
<input {...data} />
</div>
</React.Fragment>
}
initialValues = function () {
let { prefix, fields } = this.props;
prefix = prefix ? prefix + CONCAT_ID_BASES : '';
fields ? fields.map((field) => {
const newKey = `${prefix}${field.key}`
this.setState((prevState) => {
let newData = { ...prevState.data };
newData[newKey] = field.value.value;
return { data: newData };
})
}) : null;
}
componentDidMount() {
this.initialValues();
}
componentDidUpdate() {
//console.log(this.state)
//this.props.suscribeCallback(values)
}
inputGenerator(field, prefix) {
const { key, value } = field;
const { type } = value;
const textValidate = FormGenerator.textValidate;
const newKey = `${prefix}${key}`
let element = null;
const createInput = FormGenerator.createInput;
switch (true) {
case new RegExp(INPUTTYPES.TEXT.join("|"), "i").test(type):
value.type = "text";
element = createInput(newKey, value, textValidate)
break;
case new RegExp(INPUTTYPES.NUMBER.join("|"), "i").test(type):
value.type = "number";
element = createInput(newKey, value, textValidate)
break;
case new RegExp(INPUTTYPES.SELECT.join("|"), "i").test(type):
break;
default:
log.error("DATA NOT ITENDIFIED TYPE:" + type, key, value);
break;
}
return element;
}
render() {
let fields = this.props.fields;
let { prefix } = this.props;
prefix = prefix ? prefix + CONCAT_ID_BASES : ''
const { inputGenerator, onSubmit } = this;
return (
<Form
onSubmit={onSubmit}
initialValues={this.state.data}
render={({ values }) => {
return <div className="form-row">
{fields.map((field) => {
return inputGenerator(field, prefix);
})}
<pre>{JSON.stringify(values, 0, 2)}</pre>
</div>
}} />
)
}
}
export default FormGenerator;
并这样称呼它:
{
detalles ? (() => {
return <FormGenerator
suscribeCallback={this.formDataChange}
prefix={this.props.prefix}
fields={detalles} />
})() : null
}
但现在的问题是,我需要在values
外部阅读,<Form/>
这样我才能在它的父级中阅读它。
如果我包含一个回调并将其扔到渲染方法this.props.suscribeCallback(values)
中,它会尝试调用它,它会导致站点崩溃。当然这不是一个有效的解决方案,但我不知道如何解决它。
我对 Reactjs 有点陌生,所以如果这是初学者的错误,请道歉