问题描述
我已经创建了一个表单,并将数据保存到本地的json文件中。我可以保存所有数据,但带有多个选择和多个复选框的问题除外。它仅保存最后选择的一个。我正在尝试在React Hook中编写一个switch语句,以帮助保存提交的表单。我不断收到错误消息“无法识别未定义的类型”。我是新来的反应者,不知道该怎么办。
这是在我的hooks文件夹中:
export const useInputChange = (customValue,callback) => {
const [value,setValue] = useState(customValue ? customValue : "" || []);
const handleChange = (event) => {
var newValue;
switch (customValue.type) {
case "multipleSelection":
newValue = $("multipleSelection").find("option:checked");
break;
case "checkBoxChoice":
newValue = $("checkBoxChoice").find("input:checked");
break;
default:
newValue = event.target.value;
}
setValue(newValue);
if (callback) {
callback(event.target.name,newValue);
}
};
return {
value: value,handleChange: handleChange
};
};
这是我在components文件夹中的回调:
const callback = (name,value) => {
console.log("callback",name,value);
inlineData[name] = value;
setInlineData(inlineData);
console.log(inlineData);
};
jquery在控制台中工作,以提取正确的数组。
这是组件:
export const Survey = (props) => {
const [page,setPage] = useState(1);
const [isFinalPage,setIsFinalPage] = useState(false);
const [surveyValues,setSurveyValues] = useState({});
const [loadedInputs,setLoadedInputs] = useState({});
const [question,setQuestion] = useState({});
const [inlineData,setInlineData] = useState({});
const { surveyId } = props;
const triggerBackendUpdate = () => {
console.log(question);
console.log(surveyValues);
setPage(1);
setSurveyValues({});
setQuestion({});
};
useEffect(() => {
if (surveyId) {
const inputDataFile = import(`./data_${surveyId}.json`);
inputDataFile.then((response) => {
setLoadedInputs(response.default);
});
}
});
const handleSubmit = (event) => {
event.preventDefault();
event.persist();
for (let formInput of event.target.elements) {
const isText = isTextInput(formInput.type);
console.log(formInput);
if (isText) {
surveyValues[formInput.name] = formInput.value;
question[formInput.question] = formInput.question;
}
if (formInput.type === "selectMultiple") {
let selected = [].filter.call(
formInput.options,(option) => option.selected
);
console.log(formInput);
console.log(selected);
console.log(formInput.options.selected);
const values = selected.map((option) => option.value);
surveyValues[formInput.name] = values;
question[formInput.name] = formInput.question;
}
if (formInput.type === "checkBox") {
surveyValues[formInput.name] = formInput.value;
question[formInput.name] = formInput.question;
}
}
setQuestion(question);
setSurveyValues(surveyValues);
const nextPage = page + 1;
const inputs = props.inputs
? props.inputs.filter((inputoption) => inputoption.page ===
nextPage): [];
if (isFinalPage) {
triggerBackendUpdate();
} else {
if (inputs.length === 0) {
setIsFinalPage(true);
} else {
setPage(nextPage);
}
}
};
const callback = (name,value) => {
console.log("callback",value);
inlineData[name] = value;
setInlineData(inlineData);
console.log(inlineData);
};
const saveSurvey = async () => {
await fetch("/api/survey",{
method: "POST",body: JSON.stringify(inlineData),headers: {
"Content-Type": "application/json",},}).catch((error) => {
console.error(error);
});
};
const inputs = props.inputs
? props.inputs.filter((inputoption) => inputoption.page === page)
: [];
return (
<form onSubmit={handleSubmit}>
{isFinalPage !== true &&
inputs.map((obj,index) => {
let inputKey = `input-${index}-${page}`;
return obj.type === "radio" || obj.type === "checkBox" ? (
<SurveyRadioInput
object={obj}
type={obj.type}
required={props.required}
triggerCallback={callback}
question={obj.question}
defaultValue={obj.defaultValue}
name={obj.name}
key={inputKey}
/>
) : obj.type === "checkBox" ? (
<SurveyCheckBoxInput
object={obj}
type={obj.type}
required={props.required}
triggerCallback={callback}
question={obj.question}
defaultValue={obj.defaultValue}
name={obj.name}
key={inputKey}
/>
) : obj.type === "select" ? (
<SurveySelectInput
className="form-control mb-3 mt-3"
object={obj}
type={obj.type}
question={obj.question}
required={props.required}
triggerCallback={callback}
defaultValue={obj.defaultValue}
name={obj.name}
key={inputKey}
/>
) : obj.type === "selectMultiple" ? (
<SurveySelectMultipleInput
className="form-control mb-3 mt-3"
object={obj}
type={obj.type}
question={obj.question}
required={props.required}
triggerCallback={callback}
defaultValue={obj.defaultValue}
name={obj.name}
key={inputKey}
/>
) : (
<SurveyTextInput
className="mb-3 mt-3 form-control"
object={obj}
type={obj.type}
question={props.question}
required={props.required}
triggerCallback={callback}
placeholder={obj.placeholder}
defaultValue={obj.defaultValue}
name={obj.name}
key={inputKey}
/>
);
})}
{isFinalPage !== true ? (
<button name="continue-btn" className="btn btn-primary my-5 mx-5">
Continue
</button>
) : (
<Link to="/thankyou">
<button
onClick={saveSurvey}
type="button"
className="btn btn-primary my-5 mx-5"
>
Submit Survey
</button>
</Link>
)}
</form>
);
};
这是在我的输入文件夹中:
export const SurveySelectMultipleInput = (props) => {
const { object } = props;
const { value,handleChange } = useInputChange(
props.defaultValue,props.triggerCallback
);
const inputType = isTextInput(props.type) ? props.type : "";
const inputProps = {
className: props.className ? props.className : "form-control",onChange: handleChange,value: value,required: props.required,question: props.question,type: inputType,name: props.name ? props.name : `${inputType}_${props.key}`,};
console.log(value);
return (
<>
<div id={object.name}>
<h5>{props.question}</h5>
<select
{...inputProps}
name={object.name}
className={props.className}
multiple={object.multiple}
>
<option hidden value>
Select one
</option>
{object.options.map((data,index) => {
return (
<option
value={data.value}
id={`${object.name}-${index}`}
key={`${object.type}-${index}`}
className={`form-check ${props.optionClassName}`}
>
{data.label}
</option>
);
})}
</select>
</div>
</>
);
};
解决方法
在没有示例显示其行为和属性的情况下,很难确切地说明它们的行为。无论如何,我都做了一些假设并试图回答:
首先,customValue
中useInputChange
的预期类型是什么?您要一个字符串还是一个数组?那么您在type
语句中检查的switch
属性是什么?
对于jquery选择器,multipleSelection
是什么?它是用于选择元素的类名吗?然后,您的选择器必须以点a / nd开头,然后可以通过在所选元素上调用.val
方法来获取值:
newValue = $(".multipleSelection").val();
以下是使用您的代码的多个选择元素的有效示例:https://codepen.io/kaveh/pen/QWNNQMV
请注意,我必须为type
分配一个任意的VALUE
属性,才能使其与您的switch语句一起使用。
话虽如此,正如我在评论中提到的那样,建议使用ref
来访问由React创建的元素,而不是其他查询选择器(例如从jquery获得的选择器)。