我在自定义
<input type='file'/>
元素时遇到问题。
由于我是 React.js 和 JS 的新手,我不知道如何更改输入元素的默认 'Choose File'
文本,因此我找到了一个简短的教程('https://3body-net.medium.com /how-to-style-a-file-input-in-react-b6a141418341') 它有效,但我仍然有一个小错误(我认为)和一些问题。
这是文件输入自定义的组件。
import React, {useState, useRef} from "react";
const ImageInput = ({ file, setFile }) => {
const fileInput = useRef(null);
const onChange = async (event) => {
if (event.target.files && event.target.files.length > 0) {
setFile(event.target.files[0]);
}
}
return (
<>
<input
type="file"
name="image"
ref={fileInput}
onChange={onChange}
style={{ display: 'none' }}
/>
<button
className="upload-btn"
onClick={() => fileInput.current.click()}
style={{ width: '40%', fontSize: '14px', marginBottom: '10px' }}
>Upload Image</button>
</>
);
}
export default ImageInput;
这是我的父组件(用于创建玩家实体)
import React, { useState } from "react";
import axios from "axios";
import "../../assets/styles/form/adminCreatePlayerForm.css";
import ImageInput from "./ImageInput";
const CreatePlayer = () => {
const [playerData, setPlayerData] = useState({
firstName: '',
lastName: '',
photoUrl: '',
});
// probat izbacit playerImg, koristit samo photoUrl...u handleFileChange napravit isto sta i u handleSubmit s updatedPlayerData
const [playerImg, setPlayerImg] = useState(null);
const handleChange = (event) => {
setPlayerData({
...playerData,
[event.target.name]: event.target.value
});
};
// *** I don't need 'handleFileChange' anymore since I've created ImageInput component
// const handleFileChange = (event) => {
// setPlayerImg(event.target.files[0]);
// };
// *** event.preventDefault(); - stops page from reloading on submit, also if validation is done on FE
// it stops form submission and checks the validation rules
const handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('playerImg', playerImg);
axios.post("http://localhost:8080/files/upload", formData).then((response) => {
console.log(response);
const photoName = response.data.imageName;
const updatedPlayerData = ({
...playerData,
photoUrl: photoName,
});
axios.post("http://localhost:8080/players", updatedPlayerData).then((response) => {
console.log(response);
});
});
// reseting form after submit
setPlayerData({
firstName: '',
lastName: '',
photoUrl: '',
})
setPlayerImg(null);
};
return (
<div className="create-player-container">
<h1>Add New Player</h1>
<div className="create-player-form">
<form onSubmit={handleSubmit}>
<div className="create-player-form-field">
<label htmlFor="firstName">
First Name
</label>
<input
type="text"
name="firstName"
value={playerData.firstName}
onChange={handleChange}
/>
</div>
<div className="create-player-form-field">
<label htmlFor="lastName">
Last Name
<input
type="text"
name="lastName"
value={playerData.lastName}
onChange={handleChange}
/>
</label>
</div>
<div className="create-player-form-field">
<label htmlFor="profile-picture">
</label>
<ImageInput file={playerImg} setFile={setPlayerImg}/>
</div>
<button type="submit">Create</button>
</form>
</div>
</div>
);
}
export default CreatePlayer;
file
从未使用过时,ImageInput会接收2个参数(react世界中的2个道具?)?async
const onChange = async (event) => {
,声明它是异步的然后不使用await
关键字是否有意义,它有什么好处?最后出现错误 -> 当我单击“上传图像”按钮(在实际选择图像之前)时,我可以立即在控制台中看到 Axios 错误,并显示
detail: "Required part 'playerImg' is not present."
(在我上传的屏幕截图中可以看到更详细的 axios 响应。)
编辑:stackowerflow 还不允许我发布图像
由于我没有更深入的理解,所以我不明白为什么它在我选择图像之前就检测到不存在图像。
file 和 setFile 只是保存文件的状态。如果
file
没有被使用,那么你可以从这里删除它
<ImageInput setFile={setPlayerImg}/>
。
您可以安全地删除 onChange 函数的异步。
在 ImageInput 组件中添加 type="button" 您的表单会在单击此按钮后立即提交,因为它假定此按钮为
submit
按钮。
<button type="button">