我有以下简单的代码,我正在尝试将其重写为避免类并使用钩子进行学习的函数。 正如您在下面看到的,"应用程序"正在扩展"表单"。完整的代码包括"Form"中的其他函数,例如,由"handleChange"调用并修改状态中的"错误"项的验证函数。 请注意,"表单"不是"应用程序"的一部分,因为表单将被其他组件(例如登录组件(重用。
我的主要问题:
1-根据文档,他们似乎不鼓励使用继承,如何在不使用"扩展"(并保留类(的情况下重写它?
2-如何在没有类的情况下重写它?
到目前为止,我想到的唯一想法是将form.jsx中的所有函数重写为独立的函数,并从App调用它们(见下文(。但这意味着要编写大量的 prop 和参数(特别是当验证被添加为"错误"、"setErrors"、"模式"等时,将从"App"发送到"renderInput",从这里发送到"handleChange"等。 它可以工作,但代码不如以前干净...
应用.js
class App extends Form {
state = {
data: { username: "", password: "" },
};
render() {
return (
<form action="">
{this.renderInput("username", "Username")}
{this.renderInput("password", "Password", "password")}
</form>
);
}
}
表单.jsx
class Form extends Component {
state = {
data: {},
};
handleChange = ({ currentTarget }) => {
const data = { ...this.state.data };
data[currentTarget.name] = currentTarget.value;
this.setState({ data });
};
renderInput(name, label, type = "text") {
const { data, errors } = this.state;
return (
<Input
name={name}
type={type}
value={data[name]}
label={label}
onChange={this.handleChange}
/>
);
}
render() {
return null;
}
}
export default Form;
输入.jsx
const Input = ({ name, label, ...rest }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input {...rest} name={name} id={name} className="form-control" />
</div>
);
};
尝试将其更改为函数:
应用.jsx
const App = () => {
const [user, setUser] = useState({ username: "", password: "" });
return (
<form action="">
{renderInput("username", "Username", user, setUser)}
{renderInput("password", "Password", user, setUser, "password")}
</form>
);
};
表单.jsx
export function handleChange({ currentTarget }, data, setData) {
setData({ ...data, [currentTarget.name]: currentTarget.value });
}
export function renderInput(name, label, data, setData, type = "text") {
return (
<Input
name={name}
type={type}
value={data[name]}
label={label}
onChange={e => handleChange(e, data, setData)}
/>
);
}
提前感谢,如果您需要更好的解释或完整的代码,请告诉我。
将form
移动到Form
组件,并传递输入属性数组以生成输入:
应用.jsx
const App = () => {
const [user, setUser] = useState({ username: "", password: "" });
const inputList = [
{name: "username", label: "Username", value: user.username},
{name: "password", label: "Password", value: user.password, type: "password"}
]
return (
<Form inputList={inputList} setData={setUser} />
);
};
表单.jsx
const Form = ({ inputList, setData }) => {
const handleChange = ({ currentTarget }) => {
const { name, value } = currentTarget;
setData(prevData => ({ ...prevData, [name]: value }));
};
return (
<form action="">
{
inputList.map(({ name, label, value, type = "text" }) =>
<Input
key={name}
name={name}
type={type}
value={value}
label={label}
onChange={handleChange}
/>
)
}
</form>
);
}