javascript - 禁用下一个按钮,直到使用 Reactjs 填写表单
问题描述
我需要禁用下一个按钮,直到用户填写表单。完整的组件附在此处。我需要禁用下一个按钮。此表单是在 react-hook-from 中使用材质 UI 构建的 useFrom()。这与 address1、city 和 zip 字段的 API 数据集成。下一个按钮是支付网关的流程。所以我需要禁用按钮,直到表单字段完成。只需要验证是否填写了所有字段,一旦完成,下一步就是显示点击。
const AddressForm = ({ checkoutToken, test }) => {
const [shippingCountries, setShippingCountries] = useState([]);
const [shippingCountry, setShippingCountry] = useState('');
const [shippingSubdivisions, setShippingSubdivisions] = useState([]);
const [shippingSubdivision, setShippingSubdivision] = useState('');
const [shippingOptions, setShippingOptions] = useState([]);
const [shippingOption, setShippingOption] = useState('');
const methods = useForm();
const fetchShippingCountries = async (checkoutTokenId) => {
const { countries } = await commerce.services.localeListShippingCountries(checkoutTokenId);
setShippingCountries(countries);
setShippingCountry(Object.keys(countries)[0]);
};
const fetchSubdivisions = async (countryCode) => {
const { subdivisions } = await commerce.services.localeListSubdivisions(countryCode);
setShippingSubdivisions(subdivisions);
setShippingSubdivision(Object.keys(subdivisions)[0]);
};
const fetchShippingOptions = async (checkoutTokenId, country, stateProvince = null) => {
const options = await commerce.checkout.getShippingOptions(checkoutTokenId, { country, region: stateProvince });
setShippingOptions(options);
setShippingOption(options[0].id);
};
useEffect(() => {
fetchShippingCountries(checkoutToken.id);
}, []);
useEffect(() => {
if (shippingCountry) fetchSubdivisions(shippingCountry);
}, [shippingCountry]);
useEffect(() => {
if (shippingSubdivision) fetchShippingOptions(checkoutToken.id, shippingCountry, shippingSubdivision);
}, [shippingSubdivision]);
return (
<>
<Typography variant="h6" gutterBottom>Shipping address</Typography>
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit((data) => test({ ...data, shippingCountry, shippingSubdivision, shippingOption }))}>
<Grid container spacing={3}>
<FormInput required name="firstName" label="First name" />
<FormInput required name="lastName" label="Last name" />
<FormInput required name="address1" label="Address line 1" />
<FormInput required name="email" label="Email" />
<FormInput required name="city" label="City" />
<FormInput required name="zip" label="Zip / Postal code" />
<Grid item xs={12} sm={6}>
<InputLabel>Shipping Country</InputLabel>
<Select value={shippingCountry} fullWidth onChange={(e) => setShippingCountry(e.target.value)}>
{Object.entries(shippingCountries).map(([code, name]) => ({ id: code, label: name })).map((item) => (
<MenuItem key={item.id} value={item.id}>
{item.label}
</MenuItem>
))}
</Select>
</Grid>
<Grid item xs={12} sm={6}>
<InputLabel>Shipping Subdivision</InputLabel>
<Select value={shippingSubdivision} fullWidth onChange={(e) => setShippingSubdivision(e.target.value)}>
{Object.entries(shippingSubdivisions).map(([code, name]) => ({ id: code, label: name })).map((item) => (
<MenuItem key={item.id} value={item.id}>
{item.label}
</MenuItem>
))}
</Select>
</Grid>
<Grid item xs={12} sm={6}>
<InputLabel>Shipping Options</InputLabel>
<Select value={shippingOption} fullWidth onChange={(e) => setShippingOption(e.target.value)}>
{shippingOptions.map((sO) => ({ id: sO.id, label: `${sO.description} - (${sO.price.formatted_with_symbol})` })).map((item) => (
<MenuItem key={item.id} value={item.id}>
{item.label}
</MenuItem>
))}
</Select>
</Grid>
</Grid>
<br />
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Button component={Link} variant="contained" to="/cart" color="secondary">Back to Cart</Button>
<Button type="submit" variant="contained" color="primary">Next</Button>
</div>
</form>
</FormProvider>
</>
);
};
解决方案
您可以使用前面提到的有效函数
const isValid = shippingCountries && shippingCountry && shippingSubdivisions && shippingSubdivision && shippingOptions && shippingOption
<Button disabled={!isValid} />
当您使用 FormProvider 和 useForm() 时,我认为您使用的是 react-hook-form?如果是,那就更容易了,因为它有一个集成的验证器。
例如你可以这样使用它
const { register, handleSubmit, setValue } = useForm();
....
<form onSubmit={methods.handleSubmit((data) => test({ ...data, shippingCountry, shippingSubdivision, shippingOption }))}>
<FormInput {...register("firstName, {required: true})} />
</form
使用 setValue 您可以从外部设置表单的值(例如您的 useEffect 函数)
setValue([{ firstName: name }, { secondOption: option }]);
推荐阅读
- android - Android:根据 RecyclerView 的宽度调整 RecyclerView 数据项的大小
- postgresql - 监控 Postgres 上的查询
- python - 为什么我的字计数器在我第一次运行时产生的输出与第二次不同?
- c# - 使用 C# 在 SQL Server 中增加一年后月份不增加
- node.js - 使用 Homebrew 在 macOS 上安装 node.js + npm 会防止 EACCES 权限错误吗?
- android - 在 RxJava 中“加入”一个 Observable 列表
- java - 为什么 JIT 编译器不提前编译字节码?
- php - 在 try-catch 块中省略 $ex 变量
- c++ - 如果您在循环内给 cin 一个意外的输入,C++ 换行符会自动作为输入输入
- python-3.x - 如何在 Python 中使用 MPI 在不同的内核上实现简单的并行计算