我试图弄清楚如何将React与Formik的字段数组一起使用,以将可重复的表单组件嵌入到我的表单中。
我有一个正在运行的系统(我认为)。它是来自10多个来源的建议的组合,所以我开始认为我已经离开了种植园,因为必须有一种明显的方法来进行设置(但我无法弄清楚)。
此刻,我当前的方法正在生成警告:
一个组件正在将文本类型的不受控制的输入更改为 受控。输入元素不应从不受控制的切换到 控制(反之亦然)。决定使用受控还是 组件生命周期中不受控制的输入元素。更多 信息:https://reactjs.org/docs/forms.html#controlled-components
我的代码沙箱在这里:https://codesandbox.io/s/goofy-glade-lx65p?from-embed。对于那些不想使用此工具的人,沙盒中的代码粘贴在这篇文章的底部。
您可以看到可以渲染和删除可重复嵌入的表单。但是,嵌入的窗体有一个错误,指出:this.props.formik.registerField不是函数。 (在“ this.props.formik.registerField(this.props.name,this)”中,“ this.props.formik.registerField”未定义)
我不知道这意味着什么。我不在任何地方使用称为registerField的东西。我应该吗?我已经看到this post描述了如何设置初始状态来解决此警告,但是如果我在请求表单中进行设置,则会在主表单上显示一个空白表单(我不希望那样,我会只希望链接嵌入一个)。
任何人都可以看到我对国家的错吗?
表格:
import React from "react";
import { Link } from "react-router-dom";
import {
Formik,
Form,
Field,
FieldArray,
ErrorMessage,
withFormik
} from "formik";
// import * as Yup from "yup";
import Select from "react-select";
// import { fsDB, firebase, settings } from "../../../firebase";
import Requests from "./Requests";
import {
Badge,
Button,
Col,
ComponentClass,
Feedback,
FormControl,
FormGroup,
FormLabel,
InputGroup,
Table,
Row,
Container
} from "react-bootstrap";
const style2 = {
paddingTop: "2em"
};
const initialValues = {
title: "",
Requests: [],
createdAt: ""
};
class MainForm extends React.Component {
state = {
options: []
};
async componentDidMount() {
// const fsDB = firebase.firestore(); // Don't worry about this line if it comes from your config.
let options = [];
// await fsDB.collection("abs_for_codes").get().then(function (querySnapshot) {
// querySnapshot.forEach(function(doc) {
// console.log(doc.id, ' => ', doc.data());
// options.push({
// value: doc.data().title.replace(/( )/g, ''),
// label: doc.data().title + ' - ABS ' + doc.id
// });
// });
// });
this.setState({
options
});
}
handleSubmit = (formState, { resetForm }) => {
// Now, you're getting form state here!
const payload = {
...formState,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
};
console.log("formvalues", payload);
// fsDB
// .collection("project")
// .add(payload)
// .then(docRef => {
// console.log("docRef>>>", docRef);
// resetForm(initialValues);
// })
// .catch(error => {
// console.error("Error adding document: ", error);
// });
};
render() {
const { options } = this.state;
return (
<Formik
initialValues={initialValues}
onSubmit={this.handleSubmit}
render={({
errors,
status,
touched,
setFieldValue,
setFieldTouched,
handleSubmit,
isSubmitting,
dirty,
values,
arrayHelers
}) => {
return (
<div>
<Form>
<Table responsive>
<thead>
<tr>
<th>#</th>
<th>Element</th>
<th>Insights</th>
</tr>
</thead>
</Table>
{/*General*/}
<h5 className="formheading">general</h5>
<Table responsive>
<tbody>
<tr>
<td>1</td>
<td>
<div className="form-group">
<label htmlFor="title">Title</label>
<Field
name="title"
type="text"
className={
"form-control" +
(errors.title && touched.title
? " is-invalid"
: "")
}
/>
<ErrorMessage
name="title"
component="div"
className="invalid-feedback"
/>
</div>
</td>
<td className="forminsight">No insights</td>
</tr>
</tbody>
</Table>
{/*Method*/}
{/* <SoPTip /> */}
{/*Resources s*/}
<Table responsive>
<tbody>
<tr>
<td>
<label htmlFor="Requests">Request</label>
<FieldArray
name="Requests"
render={arrayHelpers => (
<React.Fragment>
{values.Requests.map((funding, i) => (
<Requests
setFieldValue={setFieldValue}
arrayHelpers={arrayHelpers}
values={values}
data={funding}
key={i}
index={i}
/>
))}
<div>
<Button
variant="link"
size="sm"
onClick={() =>
arrayHelpers.push({
title: "",
description: "",
source: "",
disclosure: "",
conflicts: ""
})
}
>
Add request
</Button>
</div>
</React.Fragment>
)}
/>
</td>
<td className="forminsight">No insights</td>
</tr>
</tbody>
</Table>
<div className="form-group">
<Button
variant="outline-primary"
type="submit"
id="ProjectId"
onClick={handleSubmit}
disabled={!dirty || isSubmitting}
onSubmit={values => console.log(values)}
>
Save
</Button>
</div>
</Form>
</div>
);
}}
/>
);
}
}
export default MainForm;
请求可重复形式:
import React from "react";
import { Field } from "formik";
import Select from "react-select";
import { Table, Button } from "react-bootstrap";
const Currencies = [
{ value: "usd", label: "United States Dollars (USD)" },
{ value: "nzd", label: "New Zealnd Dollars (NZD)" },
{ value: "gbp", label: "Pounds Sterling (GBP)" },
{ value: "cad", label: "Canadian Dollars (CAD)" }
];
class Requests extends React.Component {
render() {
const {
index,
values,
setFieldValue,
setFieldTouched,
arrayHelpers,
remove
} = this.props;
return (
<div>
<Table responsive>
<tbody>
<tr>
<td>
<div className="form-group">
<label htmlFor="RequestsTitle">Title</label>
<Field
name={`Requests.${index}.title`}
placeholder="Add a title"
className="form-control"
/>
</div>
</td>
</tr>
<tr>
<td>
<div className="form-group">
<label htmlFor="RequestsSource">Source</label>
<Field
name={`Requests.${index}.source`}
component="textarea"
rows="10"
placeholder="Leave blank and skip ahead if you don't"
className="form-control"
/>
</div>
</td>
</tr>
<tr>
<td>
<div className="form-group">
<label htmlFor="Currency">Select your currency</label>
<Select
key={`my_unique_select_keyCurrency`}
name={`Requests.${index}.Currency`}
className={"react-select-container"}
classNamePrefix="react-select"
onChange={({ value: selectedOption }) => {
console.log(selectedOption);
setFieldValue(
`Requests.${index}.Currencies`,
selectedOption
);
}}
onBlur={setFieldTouched}
options={Currencies}
/>
</div>
</td>
<td className="forminsight">No insights</td>
</tr>
<tr>
<td>
<div className="form-group">
<label htmlFor="RequestsAmount">
What amount of funding are you seeking?
</label>
<Field
name={`Requests.${index}.amount`}
type="text"
placeholder="Enter a number without a currency symbol"
className={"form-control"}
/>
</div>
</td>
<td className="forminsight">No insights</td>
</tr>
<tr>
<td>
<div className="form-group">
<label htmlFor="RequestsDisclosure">Disclosure</label>
<Field
name={`Requests.${index}.disclosure`}
component="textarea"
rows="10"
placeholder="Consider."
className="form-control"
/>
</div>
</td>
</tr>
<tr>
<td>
<div className="form-group">
<label htmlFor="RequetsConflicts">Conflicts</label>
<Field
name={`Requests.${index}.conflicts`}
component="textarea"
rows="10"
placeholder="Take a look at the checklist. "
className="form-control"
/>
</div>
</td>
<td className="forminsight">No insights</td>
</tr>
<tr>
<td>
<div className="form-group">
<label htmlFor="RequestsBudget">
Do you have a budget for how this funding will be deployed?
</label>
<Field
name={`Requests.${index}.budget`}
component="textarea"
rows="10"
placeholder="Leave blank if you don't."
className="form-control"
/>
</div>
</td>
<td className="forminsight">No insights</td>
</tr>
</tbody>
</Table>
<Button
variant="outline-secondary"
size="sm"
onClick={() => arrayHelpers.remove(index)}
>
Remove this request
</Button>
</div>
);
}
}
export default Requests;
答案 0 :(得分:0)
我发现该警告的原因是您的Requests
中有initialValues
,但是您在表单中使用了fundingRequests
。
当我改变
<Field
name={`fundingRequests.${index}.title`}
placeholder="Add a title"
className="form-control"
/>
到
<Field
name={`Requests.${index}.title`}
placeholder="Add a title"
className="form-control"
/>
将不再有警告。 让我知道这是否不能解决问题