Subir Archivos de Imagen en React
En este post se explica como se podría capturar una imagen con react, para posteriormente poder realizar con ella las acciones requeridas.
Para ello empezaremos creándonos dos Componentes React:
1. FileUploader
export default class FileUploader extends Component {
render() {
let state = this.state,
props = this.props;
return (
<form name="form" id="form">
</form>
);
}
}
FileUploader.propTypes = propTypes;
FileUploader.defaultProps = defaultProps;
2.Imágenes:
import React, { Component } from "react";
import FileUploader from "./FileUploader";
import axios from "axios";
export default class Imagenes extends Component {
uploader = React.createRef();
render() {
return (
<div>
<FileUploader ref={this.uploader} />
<button type="submit">
Enviar
</button>
</div>
);
}
}
Como podemos comprobar FileReader lo usaremos dentro de imágenes.js. FileReader contendrá el formulario del que posteriormente será utilizado para recoger la imagen
<form name="form" ref={this.formRef} id="form">
<label
onDragEnter={this.onDragEnter}
onDragLeave={this.onDragLeave}
onDragOver={this.onDragOver}
onDrop={this.onDrop}
>
<img src={state.imageSrc} />
<i className="icon icon-upload"></i>
<input
type="file"
accept="image/*"
onChange={this.onFileChange}
ref="input"
/>
</label>
</form>
Añadimos el constructor de FileReader:
constructor(props) {
super(props);
this.state = {
active: false,
imageSrc: "",
imageName: "",
image: [],
loaded: false
};
this.onDragEnter = this.onDragEnter.bind(this);
this.onDragLeave = this.onDragLeave.bind(this);
this.onDrop = this.onDrop.bind(this);
this.onFileChange = this.onFileChange.bind(this);
}
Creamos dentro del FileReader los métodos que serán llamados según el evento:
onDragEnter(e) {
this.setState({ active: true });
}
onDragLeave(e) {
this.setState({ active: false });
}
onDragOver(e) {
e.preventDefault();
}
onDrop(e) {
e.preventDefault();
this.setState({ active: false });
this.onFileChange(e, e.dataTransfer.files[0]);
}
onFileChange(e, file) {
console.log("on-file-change");
var file = file || e.target.files[0],
pattern = /image-*/,
reader = new FileReader();
console.log(file.name);
if (!file.type.match(pattern)) {
alert("Formato inválido");
return;
}
console.log(this);
this.setState({ loaded: false });
reader.onload = e => {
this.setState({
imageSrc: reader.result,
loaded: true,
imageName: file.name
});
console.log(reader.result);
};
reader.readAsDataURL(file);
}
Y lo ultimo aquí seria añadir dentro de FileReader métodos por el cual leeremos características de lo que hemos seleccionado en el formulario:
getFileName() {
return this.state.imageName;
}
getFileObject() {
return this.refs.input.files[0];
}
getFileString() {
return this.state.imageSrc;
}
FileReader debería quedar asi:
import React, { Component } from "react";
export default class FileUploader extends Component {
form = React.createRef();
state = {
active: false,
imageSrc: "",
imageName: "",
image: [],
loaded: false
};
constructor(props) {
super(props);
this.state = {
active: false,
imageSrc: "",
imageName: "",
image: [],
loaded: false
};
this.onDragEnter = this.onDragEnter.bind(this);
this.onDragLeave = this.onDragLeave.bind(this);
this.onDrop = this.onDrop.bind(this);
this.onFileChange = this.onFileChange.bind(this);
}
onDragEnter(e) {
this.setState({ active: true });
}
onDragLeave(e) {
this.setState({ active: false });
}
onDragOver(e) {
e.preventDefault();
}
onDrop(e) {
e.preventDefault();
this.setState({ active: false });
this.onFileChange(e, e.dataTransfer.files[0]);
}
onFileChange(e, file) {
console.log("on-file-change");
var file = file || e.target.files[0],
pattern = /image-*/,
reader = new FileReader();
console.log(file.name);
if (!file.type.match(pattern)) {
alert("Formato inválido");
return;
}
console.log(this);
this.setState({ loaded: false });
reader.onload = e => {
this.setState({
imageSrc: reader.result,
loaded: true,
imageName: file.name
});
console.log(reader.result);
};
reader.readAsDataURL(file);
}
getFileName() {
return this.state.imageName;
}
getFileObject() {
return this.refs.input.files[0];
}
getFileString() {
return this.state.imageSrc;
}
render() {
let state = this.state,
props = this.props;
return (
<form name="form" ref={this.formRef} id="form">
<label
onDragEnter={this.onDragEnter}
onDragLeave={this.onDragLeave}
onDragOver={this.onDragOver}
onDrop={this.onDrop}
>
<img src={state.imageSrc} />
<i className="icon icon-upload"></i>
<input
type="file"
accept="image/*"
onChange={this.onFileChange}
ref="input"
/>
</label>
</form>
);
}
}
Por consiguiente se trabajara sobre imagenes.js, que contiene FileReader y se dedica a realizar las acciones que queramos con lo que nos ofrece este FileReader.
Incluimos dentro del render FileReader:
render() {
return (
<div>
<FileUploader ref={this.uploader} />
<button type="submit" onClick={this.onClick}>
Enviar
</button>
</div>
);
}
Indicamos el constuctor y la referencia a FileReader de imagenes:
uploader = React.createRef();
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
Por ultimo añadimos las acciones que se requieran para la trata del fichero
onClick(e) {
e.preventDefault();
var url =
"https://apiempleadosier.azurewebsites.net/api/Prueba/InsertarPrueba",
formData = new FormData(document.getElementById("form"));
var urlimagen =
"https://apiempleadosier.azurewebsites.net/Imagen/SubirImagen";
console.log(this.uploader.current);
if (undefined === this.uploader.current) return;
formData.append("file", this.uploader.current.getFileObject());
var json = {
idPrueba: 4,
imagen: this.uploader.current.getFileName(),
texto: "Hola que tal"
};
var jsonimagen = { imagenRaw: this.uploader.current.getFileObject() };
axios.post(url, json).then(console.log("Guay"));
//axios
//.post(urlimagen, this.uploader.current.getFileObject())
//.then(console.log("Guayx2"));
}
Yo he utilizado un servicio de azure en que se puede hacer post con un objeto, que en el api he denominado como prueba y tiene tres campos, idPrueba, imagen y texto.
El campo imagen recoge el nombre del fichero que FileReader ha recogido.
imágenes.js debe quedar de esta forma:
import React, { Component } from "react";
import FileUploader from "./FileUploader";
import axios from "axios";
export default class Imagenes extends Component {
uploader = React.createRef();
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick(e) {
e.preventDefault();
var url =
"https://apiempleadosier.azurewebsites.net/api/Prueba/InsertarPrueba",
formData = new FormData(document.getElementById("form"));
var urlimagen =
"https://apiempleadosier.azurewebsites.net/Imagen/SubirImagen";
console.log(this.uploader.current);
if (undefined === this.uploader.current) return;
formData.append("file", this.uploader.current.getFileObject());
var json = {
idPrueba: 4,
imagen: this.uploader.current.getFileName(),
texto: "Hola que tal"
};
var jsonimagen = { imagenRaw: this.uploader.current.getFileObject() };
axios.post(url, json).then(console.log("Guay"));
//axios
//.post(urlimagen, this.uploader.current.getFileObject())
//.then(console.log("Guayx2"));
}
render() {
return (
<div>
<FileUploader ref={this.uploader} />
<button type="submit" onClick={this.onClick}>
Enviar
</button>
</div>
);
}
}
Y bueno esto seria todo, con esto podríamos subir imágenes con React, con Drag&Drop.
Muchas gracias por leer mi post sobre esta tecnología, para mi ha sido un placer ofrecer este conocimiento.
Autor/a: Iván Encinas Rodríguez
Curso: Microsoft MCSA Web Applications + Microsoft MCSD App Builder + Xamarin
Centro: Tajamar
Año académico: 2019-2020
Código / recursos utilizados / Otros datos de interés: https://github.com/SuperBash/ImagenesReact