我正在尝试开发一个Next.js组件(FormGenerator.jsx),根据传递给该组件的信息(对象数组)自动创建表单。在FormGenerator中,它迭代数组中的每个对象,根据对象中的数据呈现子组件(TextField,TextArea等)。我的目标是简化并保持我网站上40多个表单的一致性。
我能够渲染所有必要的组件,并将必要的信息传递给所述子组件;然而,我的问题围绕着事件处理程序。在我的父组件中,(FormGenerator),我存储所有子组件的状态,包括所述子组件的值和isInvalid布尔值。为了做到这一点,我给子组件传递了一个onBlur函数和一个P2P Change函数。onBlur函数用于验证,而P2P Change函数用于更新状态。
不幸的是,当输入值或用户点击关闭元素时,onBlur和OnBlur Change函数似乎不会被触发。我将在下面提供我的代码。为了简单起见,我删除了所有不必要的Tailwind.css样式。此外,我只包含了TextField组件,因为这是我的试运行;其他表单元素将在开发过程中添加。
src/app/page.jsx:
const components [{...}...] // List of components to generate using FormGenerator
const page = () => {
return (
...
<FormGenerator
components={components}
/>
...
)
}
export default page
src/app/components/FormGenerator.jsx:
"use client";
import React, { useState } from "react";
import TextField from "./FormGeneratorLib/TextField";
const FormGenerator = ({ title, desc, components }) => {
const initValues = ...
const initErrors = ...
const initState = { values: initValues, isInvalid: initErrors };
const [state, setState] = useState(initState);
const { values, isInvalid } = state;
...
const onBlur = (e) => {
console.error("onBlur Triggered") // Just for testing purposes
}
// function onBlur(event) { // First attempt at this
// console.error("onBlur Triggered");
// const input = event.target;
//
// // Validation
//
// setState((prev) => ({
// ...prev,
// isInvalid: {
// ...prev.isInvalid,
// [input.name]: true,
// },
// }));
// }
// Handles Component Change Event and Updates Value
const handleChange = ({ target }) =>
setState((prev) => ({
...prev,
values: {
...prev.values,
[target.name]: target.value,
},
}));
return (
...
<form>
{components.map((component, index) => {
switch (component.component) {
case "TextField":
return (
<TextField
key={index}
fieldName={component.fieldName}
label={component.label}
errorMessage={component.errorMessage}
fieldType={component.fieldType}
placeholderText={component.placeholderText}
isRequired={component.isRequired}
onChange={handleChange}
onBlur={onBlur}
value={values[component.fieldName]}
isInvalid={isInvalid[component.fieldName]}
/>
);
default:
return null;
}
})}
<button
className="disabled:opacity-30"
onClick={onSubmit}
disabled={!values[0]} // To be updated
>
Submit
</button>
</form>
...
);
};
export default FormGenerator;
src/app/components/FormGeneratorLib/TextField.jsx:
"use client"
import React, { useState } from 'react'
const TextField = ({ fieldName, label, errorMessage, fieldType, placeholderText, isRequired, value, onChange, onBlur, isInvalid }) => {
return (
<div>
<label>{label}</label>
<input
name={fieldName}
type={fieldType}
required={isRequired}
placeholder={placeholderText}
value={value}
onChange={onChange}
onBlur={onBlur}
className={
isInvalid
? 'border border-red-500'
: '...'
}
/>
<p className={
isInvalid
? '...'
: 'hidden'
}
>{errorMessage}</p>
</div>
)
}
export default TextField
在过去的两天里,我一直在不知疲倦地研究,观看许多YouTube视频,并向同行寻求帮助,但无济于事。我也试着调试我的代码,但我也遇到了问题,所以来回了很多。
最后,我希望在用户输入值时更新父状态,以便onChange和onBlur事件处理程序工作。
如果你有任何关于如何解决这个问题的建议,那将是非常感谢!以及,如果你认为有一个更好的方法来实现这个想法,请让我知道。
谢谢你,谢谢
1条答案
按热度按时间lx0bsm1f1#
使用
createContext
而不是传递props,并将所有值传递给子组件或onblur和OnBlur Change,如下所示例如:
在文本字段组件中,