我正在尝试使用 React-hooks-form 构建一个多步骤表单,其中一个步骤有一个提示选择的选择菜单和两个其他文本字段。
较大形式中的步骤具有:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import useForm from "react-hook-form";
import { withRouter } from "react-router-dom";
import { useStateMachine } from "little-state-machine";
import updateAction from "./updateAction";
import { Form, Button, Divider, Layout, Typography, Skeleton, Switch, Card, Icon, Avatar } from 'antd';
import Select from "react-select";
const { Content } = Layout
const { Text, Paragraph } = Typography;
const { Meta } = Card;
const defaultValue = {
explain: "",
managementPlan: ""
};
const issueOptions = [
{ value: "riskofharm", label: "Risk of harm" },
{ value: "informedconsent", label: "Informed consent" },
{ value: "anon", label: "Anonymity and Confidentiality" },
{ value: "deceptive", label: "Deceptive practices" },
{ value: "withdrawal", label: "Right to withdraw" },
{ value: "none", label: "No ethics considerations" }
];
const Budget = props => {
const [ethics, setEthics] = useState([]);
const [issues, setIssues] = useState([]);
const { action } = useStateMachine(updateAction);
const { register, handleSubmit, setValue, getValues, clearError } = useForm();
useEffect(() => {
register({ name: "issues" });
}, [register]);
// const onSubmit = data => {
// console.log("submit", data);
const onSubit = data => {
// console.log("submit", data);
// console.log("combined", formValues);
// combine your ethicsIssue to formValues
const { ethics, issues } = data;
const formValues = {
ethics: ethics.map((ethic, index) => ({
...ethic,
issue: issues[index]
}))
};
action(data);
props.history.push("./ProposalOutcomes");
};
const handleChange = index => selectecIssue => {
const issuesCopy = [...issues];
issuesCopy[index] = selectecIssue;
setIssues(issuesCopy);
setValue("issues", issuesCopy);
};
const addEthic = async () => {
setEthics([...ethics, defaultValue]);
};
const removeEthic = index => () => {
// get values
const { ethics, issues } = getValues({ nest: true });
// create a copy
const newEthics = [...(ethics || [])];
const newIssues = [...(issues || [])];
// remove by index
newEthics.splice(index, 1);
newIssues.splice(index, 1);
// update values
setEthics(newEthics);
setIssues(newIssues);
for (let i = 0; i < newEthics.length; i++) {
// we register the field using ethics[i].explain
// therefore, we need to setValue that way
setValue(`ethics[${i}].explain`, newEthics[i].explain);
setValue(`ethics[${i}].managementPlan`, newEthics[i].managementPlan);
}
// same goes with issue
setValue("issues", newIssues);
};
const clearEthics = () => {
setEthics([]);
setIssues([]);
setValue("issues", []);
clearError();
};
return (
<div>
<Content
style={{
background: '#fff',
padding: 24,
margin: "auto",
minHeight: 280,
width: '70%'
}}
>
<Paragraph>
<h2>Design Studio</h2>
<h4 style={{ color: '#506e8d'}}>Design a Research Proposal</h4>
</Paragraph>
<Divider />
<h2>Part 10: Ethics</h2>
<form onSubmit={handleSubmit(onSubit)}>
{ethics.map((_, index) => {
const fieldName = `ethics[${index}]`;
return (
<fieldset name={fieldName} key={fieldName}>
<label>
Issue {index}:
<Select
placeholder="Select One"
value={issues[index]}
options={issueOptions}
onChange={handleChange(index)}
/>
</label>
<label>
Explain {index}:
<input type="text" name={`${fieldName}.explain`} ref={register} />
</label>
<label>
Management Plan {index}:
<input
type="text"
name={`${fieldName}.managementPlan`}
ref={register}
/>
</label>
<Button type="danger" style={{ marginBottom: '20px', float: 'right'}} onClick={removeEthic(index)}>
Remove Ethic
</Button>
</fieldset>
);
})}
<div className="action">
<Button type="primary" style={{ marginBottom: '20px'}} onClick={addEthic}>
Add Ethic
</Button>
<br />
<Button type="button" style={{ marginBottom: '20px'}} onClick={clearEthics}>
Clear Ethics
</Button>
</div>
<input type="submit" value="next - outcomes" />
</form>
</Content>
</div>
);
}
export default withRouter(Budget);
我无法使用来自 3 个字段的内容生成单个数组。
目前,我得到了一个如下所示的 json 数据包(一个涉及道德问题,另一个涉及问题):
"ethics": [
{
"explain": "hel",
"managementPlan": "hello"
},
{
"explain": "hiiii",
"managementPlan": "hi"
}
]
,
"issues": [
{
"value": "withdrawal",
"label": "Right to withdraw"
},
{
"value": "deceptive",
"label": "Deceptive practices"
}
]
我被困在这个表格上,出现一个错误,上面写着:无法读取未定义的地图。
错误消息突出显示指向此行的问题:
{ethics.map((_, index) => {
我期待 on submit 函数将单个数组中的 3 个表单字段推送到 updateAction,但这没有发生,我看不出我需要做什么才能使其正常工作。
有没有人使用 react-hook-forms 中的字段数组成功地将选择菜单与可重复的表单字段集成在一起?