目前,我有我的 React 应用程序,我正在其中处理表单。我有一个图像字段,应该允许上传图像文件,如
jpeg
、png
、gif
等。但由于某种原因,它不起作用。我尝试了 .test()
方法是的。但它不起作用。
这是我的代码。
import React, { useState } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import {
Grid,
Row,
Col,
FormControl,
Button,
FormGroup,
ControlLabel,
} from "react-bootstrap";
import { string, number } from "yup";
import * as Yup from "yup";
import { v4 as uuidv4 } from "uuid";
import { addPlace } from "../slice/touristPlacesSlice";
import "bootstrap/dist/css/bootstrap.min.css";
import "./FormComponent.css";
function FormComponent() {
const place = useSelector((state) => state.touristPlace.touristPlace);
const [touristPlace, setTouristPlace] = useState(
place || {
name: "",
address: "",
rating: "",
type: "",
picture: "",
idx: uuidv4(),
}
);
const dispatch = useDispatch();
const [errorLog, setErrorLog] = useState({});
const validationSchema = Yup.object().shape({
name: Yup.string().required("Name of the place is required."),
address: Yup.string().required("Address of the place is required."),
rating: Yup.number()
.required("Must have to be a number between 1 to 5")
.positive()
.min(1)
.max(5),
picture: Yup.string().required("Please select a valid image file."),
});
const handleReset = () => {
setTouristPlace({
name: "",
address: "",
rating: "",
type: "",
picture: null,
idx: uuidv4(),
});
setErrorLog({});
};
const handleSubmit = async (e) => {
e.preventDefault();
try {
await validationSchema.validate(touristPlace, { abortEarly: false });
dispatch(addPlace(touristPlace));
setTouristPlace({
name: "",
address: "",
rating: "",
type: "",
picture: null,
idx: uuidv4(),
});
setErrorLog({});
} catch (error) {
const newErrorLog = {};
error.inner.forEach(err => {
newErrorLog[err.path] = err.message;
});
setErrorLog(newErrorLog);
}
};
const handleChange = (e) => {
if (e.target.type === "file") {
setTouristPlace((prev) => ({
...prev,
picture: URL.createObjectURL(e.target.files[0]),
}));
} else {
const { name, value } = e.target;
setTouristPlace((prevPlace) => ({
...prevPlace,
[name]: value,
}));
}
};
return (
<div>
<Grid>
<h1 className="text-center">Add a new Tourist Place</h1>
<br />
<FormGroup className="addForm">
<Row>
<Col xs={12} sm={2}>
<ControlLabel>Name</ControlLabel>
</Col>
<Col xs={12} sm={10}>
<FormControl
type="name"
placeholder="Name"
name="name"
value={touristPlace.name}
onChange={handleChange}
/>
{errorLog.name && <span style={{ color: "red" }}>{errorLog.name}</span>}
</Col>
</Row>
<Row>
<Col xs={12} sm={2}>
<ControlLabel>Address</ControlLabel>
</Col>
<Col xs={12} sm={10}>
<FormControl
type="text"
placeholder="Address"
name="address"
value={touristPlace.address}
onChange={handleChange}
/>
{errorLog.address && <span style={{ color: "red" }}>{errorLog.address}</span>}
</Col>
</Row>
<Row>
<Col xs={12} sm={2}>
<ControlLabel>Rating</ControlLabel>
</Col>
<Col xs={12} sm={10}>
<FormControl
type="number"
name="rating"
value={touristPlace.rating}
onChange={handleChange}
/>
{errorLog.rating && <span style={{ color: "red" }}>{errorLog.rating}</span>}
</Col>
</Row>
<Row>
<Col xs={12} sm={2}>
<ControlLabel>Type</ControlLabel>
</Col>
<Col xs={12} sm={10}>
<FormControl
componentClass="select"
placeholder="select"
name="type"
onChange={handleChange}
>
<option value="select">Beach</option>
<option value="other">Hill</option>
<option value="other">Fountain</option>
<option value="other">Landmark</option>
</FormControl>
</Col>
</Row>
<Row>
<Col xs={12} sm={2}>
<ControlLabel>Picture</ControlLabel>
</Col>
<Col xs={12} sm={10}>
<FormControl
type="file"
style={{ width: "100%" }}
name="picture"
onChange={handleChange}
accept='image/png, image/gif, image/jpeg'
/>
{errorLog.picture && <span style={{ color: "red" }}>{errorLog.picture}</span>}
</Col>
</Row>
<Row>
<Col xsOffset={10}>
<div className="button-group text-right">
<Button bsStyle="success" onClick={handleSubmit}>
Submit
</Button>
<Button bsStyle="warning" onClick={handleReset}>
Reset
</Button>
</div>
</Col>
</Row>
<Row>
<Col xsOffset={10}>
<Link
to="/list"
style={{ color: "#0aaaec" }}
onClick={handleReset}
>
Back to Tourist Place List.
</Link>
</Col>
</Row>
</FormGroup>
</Grid>
</div>
);
}
export default FormComponent;
您正在尝试验证图片字段以确保仅接受有效的图像文件(jpeg、png、gif)。目前,您在图片字段上使用带有 string() 方法的 Yup 模式。但是,由于它是文件输入字段,因此您应该尝试使用 Yup 的 mix() 模式类型进行文件验证。尝试这样的事情,
picture: Yup.mixed()
.test(
"fileType",
"Please select a valid image type",
(value) => value && ['image/jpeg', 'image/png', 'image/gif'].includes(value.type)
)
.required("Please select a valid image file.")