这里有很多这样的例子,但似乎无法找到任何反应。我设法将vanilla js转换为反应但得到an error。
答案看起来很简单所以我在这里做出反应:
getInitialState: function(){
return{file: []}
},
_onChange: function(){
// Assuming only image
var file = this.refs.file.files[0];
var reader = new FileReader();
var url = reader.readAsDataURL(file);
console.log(url) // Would see a path?
// TODO: concat files for setState
},
render: function(){
return(
<div>
<form>
<input
ref="file"
type="file"
name="user[image]"
multiple="true"
onChange={this._onChange}/>
</form>
{/* Only show first image, for now. */}
<img src={this.state.file[0} />
</div>
)
};
基本上我见过的所有答案都显示了我所拥有的东西。 React应用程序有什么区别吗?
关于答案:
答案 0 :(得分:23)
没有区别,只需在load
事件结束时阅读您的图片。在load end
事件处理程序中,只需说明您的状态:
getInitialState: function(){
return{file: []}
}
_onChange: function(){
// Assuming only image
var file = this.refs.file.files[0];
var reader = new FileReader();
var url = reader.readAsDataURL(file);
reader.onloadend = function (e) {
this.setState({
imgSrc: [reader.result];
})
}.bind(this);
console.log(url) // Would see a path?
// TODO: concat files
},
render: function(){
return(
<div>
<form>
<input
ref="file"
type="file"
name="user[image]"
multiple="true"
onChange={this_onChange}/>
</form>
{/* Only show first image, for now. */}
<img src={this.state.imgSrc} />
</div>
)
}
答案 1 :(得分:5)
这是一个简单有效的解决方案,可显示所有选定的图像
Set.unionMany
答案 2 :(得分:3)
扩展到Cels' answer,并避免将createObjectURL
设置为@El Anonimo warns about导致内存泄漏,我们可以使用useEffect
创建预览并像这样卸载组件后进行清理< / p>
useEffect(() => {
// create the preview
const objectUrl = URL.createObjectURL(selectedFile)
setPreview(objectUrl)
// free memory when ever this component is unmounted
return () => URL.revokeObjectURL(objectUrl)
}, [selectedFile])
完整的代码可能看起来像这样
export const ImageUpload = () => {
const [selectedFile, setSelectedFile] = useState()
const [preview, setPreview] = useState()
// create a preview as a side effect, whenever selected file is changed
useEffect(() => {
if (!selectedFile) {
setPreview(undefined)
return
}
const objectUrl = URL.createObjectURL(selectedFile)
setPreview(objectUrl)
// free memory when ever this component is unmounted
return () => URL.revokeObjectURL(objectUrl)
}, [selectedFile])
const onSelectFile = e => {
if (!e.target.files || e.target.files.length === 0) {
setSelectedFile(undefined)
return
}
// I've kept this example simple by using the first image instead of multiple
setSelectedFile(e.target.files[0])
}
return (
<div>
<input type='file' onChange={onSelectFile} />
{selectedFile && <img src={preview} /> }
</div>
)
}
答案 3 :(得分:2)
请这对我来说很完美
state = {
img: logo
}
handleChangeImage = e => {
this.setState({[e.target.name]: URL.createObjectURL(e.target.files[0])})
}
<input type="file" id="img" name="img" accept="image/*" className="w-100" onChange={this.handleChangeImage}/>
<img src={this.state.img} alt="img"/>
查看链接以获取更多详细信息https://medium.com/@650egor/react-30-day-challenge-day-2-image-upload-preview-2d534f8eaaa
答案 4 :(得分:1)
您可以使用base64并将其结果用于img src。这里我使用的是打字稿,但是您可以对纯JS使用相同的逻辑
(file: Blob):Promise< string | ArrayBuffer | null> => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
}),
答案 5 :(得分:0)
有我的解决方案。非常简单易用。
JSX
<form onSubmit={this.onSubmit} >
<input
ref="uploadImg"
type="file"
name="selectedFile"
onChange={this._onChange}
/>
</form>
<img src={this.state.imageUrl} />
功能
_onChange = (e) => {
const file = this.refs.uploadImg.files[0]
const reader = new FileReader();
reader.onloadend = () => {
this.setState({
imageUrl: reader.result
})
}
if (file) {
reader.readAsDataURL(file);
this.setState({
imageUrl :reader.result
})
}
else {
this.setState({
imageUrl: ""
})
}
}
当然你需要像imageUrl
这样的状态,这是我们在jsx中的src。
答案 6 :(得分:0)
我度过了疯狂的时光,试图使其与多个文件一起使用,因此,如果其他任何人都遇到了这个问题,那么您就可以这样做:
const onFileChange = e => {
e.preventDefault();
const filesList = e.target.files;
if (filesList.length === 0) return;
//Spread array to current state preview URLs
let arr = [...data.imagePreviewUrls];
for (let i = 0; i < filesList.length; i++) {
const file = filesList[i];
const reader = new FileReader();
reader.onload = upload => {
//push new image to the end of arr
arr.push(upload.target.result);
//Set state to arr
setData({
...data,
imagePreviewUrls: arr
});
};
reader.readAsDataURL(file);
}
};
基本上,for循环在第一个onload事件触发之前就已解决,从而在每次迭代时重置状态。要解决此问题,只需在for循环外创建一个数组,然后在加载时将新项目推送到该数组即可。即使用户关闭了文件对话框,并且以后选择上传更多文件,只要状态尚未重置,它都将处理多个文件。
答案 7 :(得分:0)
这是基于@Mohammed的答案以及使用方法的示例
const loadImage = (file: Blob) =>
new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () =>
typeof reader.result === "string" ? resolve(reader.result) : reject(reader.result);
reader.onerror = error => reject(error);
});
export const FilePreview: React.FC<{ file: File }> = ({ file }) => {
const [imageUrl, setImageUrl] = React.useState<string | undefined>(undefined);
React.useEffect(() => {
loadImage(file).then(setImageUrl);
}, [file]);
return (
<div>
{imageUrl && <img src={imageUrl} alt={file.name} />}
<div>{file.name}</div>
</div>
);
};
答案 8 :(得分:0)
尝试多次上传和预览:
import React,{useState} from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import PhotoCamera from '@material-ui/icons/PhotoCamera';
const useStyles = makeStyles((theme) => ({
root: {
'& > *': {
margin: theme.spacing(1),
},
},
input: {
display: 'none',
},
}));
export default function UploadButtons() {
const classes = useStyles();
const [files,setFile]=useState([]);
const handlerFile=(e)=>{
console.log(e.target.files);
let allfiles=[]
for(let i=0;i<e.target.files.length;i++){
allfiles.push(e.target.files[i]);
}
if(allfiles.length>0){
setFile(allfiles);
}
};
return (
<div className={classes.root}>
{files.map((file, key) => {
return (
<div key={key} className="Row">
<span className="Filename">
{file.name}
<img src={URL.createObjectURL(file)} alt={file.name} />
</span>
</div>
)
})}
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
onChange={handlerFile}
/>
<label htmlFor="contained-button-file">
<Button variant="contained" color="primary" component="span">
Upload
</Button>
</label>
);
}
答案 9 :(得分:0)
1. image with preview and close button
import React,{useState} from "react";
export default function App() {
const [preview,setPreview] = useState([]);
const maxLength = 3;
const onSelectFile=(e)=>{
for (var i=0;i < e.target.files.length;i++){
arrayofFiles.push(e.target.files[i]);
}
let images = [];
arrayofFiles.map((e)=>{
const ImageUrl = URL.createObjectURL(e);
images.push(ImageUrl)
})
setPreview(images)
}
const removeImageFromArray=(e)=>{
const index = e.target.id;
let newPreview = [...preview];
newPreview.splice(index,1);
setPreview(newPreview);
}
return (
<div className="App">
<h1>Image view and close</h1>
<input type="file" name="file" multiple onChange={onSelectFile}/>
{preview.map((img,index)=>
(
<div key={index}>
<img src={img} id={index} alt="pic1" width="250" height="250" />
<button
id={index}
key={index}
onClick={(e) => {
removeImageFromArray(e);
}}
>
Close
</button>
</div>
)
)}
</div>
);
}
答案 10 :(得分:-2)
-构造函数
constructor(props) {
super(props);
this.state = {
imgRef: ""
};
}
-功能
filePreview(e) {
const file = e.target.files[0];
this.setState({
imgRef: URL.createObjectURL(file)
});
}
-HTML
<input
type="file"
name="photo"
onChange={this.fileSelectHandler.bind(this)}
/>
<img src={this.state.imgRef} />
答案 11 :(得分:-2)
URL.createObjectURL(文件) 简短而精细的解决方案