
Los memes son geniales, son una forma muy divertida de describir ideas y opiniones. Asà que no es casualidad que elegà una aplicación de generador de memes como proyecto final en mi curso gratuito React en Scrimba. La aplicación funciona extrayendo una imagen aleatoria de meme de una API y colocando su texto sobre ella para crear su propio meme personalizado.
Entonces, en este artĆculo, te darĆ© una guĆa paso a paso para crear la aplicación. Si alguna vez se confunde, tambiĆ©n puede seguir estos pasos en el curso Scrimba, comenzando en esta conferencia.
Y luego, si le gusta mi estilo de enseƱanza y estĆ” de humor para un desafĆo mĆ”s difĆcil despuĆ©s de completar este tutorial, consulte mi próximo curso avanzado sobre Scrimba.
Nota: ya debe estar bastante familiarizado con algunos de los conceptos fundamentales de React, como componentes, estado, accesorios y mĆ©todos de ciclo de vida. AdemĆ”s, este tutorial no usa Hooks, pero en mi próximo curso cubriremos los Hooks en profundidad y practicaremos muchĆsimo su uso.
1. Crear el repetitivo y representar un componente de la aplicación

Lo primero que debemos hacer es crear el código repetitivo para la aplicación. Para hacer esto, importamos
React
y ReactDOM
utilizamos ReactDOM
para representar un componente llamado App
, que crearemos mƔs adelante. Luego colocamos el App
componente en la 'raĆz'. TambiĆ©n importamos App
desde su archivo "./App"
, que crearemos en breve.// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
Luego creamos nuestro
App.js
archivo. En Ʃl, creamos un componente funcional llamado App
que, por ahora, devuelve un simple <h1>
. Luego lo exportamos. El <h1>
nos permite verificar que la aplicación se muestre correctamente en la pantalla.import React from 'react';
function App() {
return <h1>Hello world!</h1>;
}
export default App;
El resultado resultante es este:


2. Crear los componentes de encabezado y MemeGenerator

A continuación, creamos los componentes Header y MemeGenerator. El encabezado solo mostrarÔ elementos, mientras que MemeGenerator llamarÔ a la API y retendrÔ los datos en estado.
Comencemos creando el
Header.js
archivo. Dado que Header es un componente que solo se usa para mostrar, debe ser un componente funcional. Por ahora, el componente deberĆa devolver un simple <h1>
. DespuƩs de crearlo, exportamos el encabezado.import React from 'react';
function Header() {
return <h1>HEADER</h1>;
}
export default Header;
A continuación, creamos el
MemeGenerator.js
archivo. Como el MemeGenerator
componente retendrĆ” datos y realizarĆ” llamadas a una API, debe ser un componente de clase. TodavĆa necesitamos importar React, y dado que va a ser un componente de clase, tambiĆ©n importaremos Component
(que es una importación con nombre ).
MemeGenerator necesita un estado
constructor()
que llame super()
y ya que estarĆ” en estado de espera, le agregamos un estado vacĆo ahora. Al igual que en el componente Encabezado, mostramos un sencillo <h1>
para comenzar. Luego exportamos MemeGenerator.import React, { Component } from 'react';
class MemeGenerator extends Component {
constructor() {
super();
this.state = {}; //empty state
}
render() {
return <h1>MEME GENERATOR SECTION</h1>;
}
}
export default MemeGenerator;
Ahora, importamos encabezado y MemeGenerator
App.js
y creamos una instancia de cada uno en nuestro componente de aplicación. Para mostrar los componentes correctamente, los envolvemos en a <div>
.import React from 'react';
import Header from './Header';
import MemeGenerator from './MemeGenerator';
function App() {
return (
<div>
<Header />
<MemeGenerator />
</div>
);
}
export default App;
3. Completando el componente Encabezado.
Para completar el
<Header>
componente, agregamos una imagen trollface insertando una <img>
etiqueta y configurando el src en la URL de la imagen. Luego agregamos una <p>
etiqueta con el nombre de nuestra aplicación y las envolvemos en la <header>
etiqueta semƔntica HTML5 .function Header() {
return (
<header>
<img
src='http://www.pngall.com/wp-content/uploads/2016/05/Trollface.png'
alt='Problem?'
/>
<p>Meme Generator</p>
</header>
);
}
Como el estilo estĆ” fuera del alcance de este curso, los estilos CSS ya se han creado y aplicado a la
<header>
etiqueta. El resultado es este:
Dicho esto, los alumnos siempre pueden jugar con el estilo y perfeccionar sus habilidades de CSS por sĆ mismos. Con el
<Header/>
ahora completo, el resto del desafĆo tendrĆ” lugar en<MemeGenerator/>
4. Estado de inicialización

Ahora tenemos que inicializar el estado para que guarde un texto superior, un texto inferior y una imagen aleatoria, que ya se suministra.
Para hacer esto, construimos el objeto vacĆo que colocamos en
<MemeGenerator/>
cuando lo construimos originalmente. Inicializamos topText
y bottomText
como cadenas vacĆas y randomImg
como la URL proporcionada.class MemeGenerator extends Component {
constructor() {
super();
this.state = {
topText: '',
bottomText: '',
randomImg: 'http://i.imgflip.com/1bij.jpg'
};
}
}
5. Realizar la llamada API

A continuación, realizamos una llamada API a la URL proporcionada y guardamos los datos devueltos (que es una matriz que se encuentra
Cuando necesitamos cargar datos desde un punto final para usar en nuestro componente, un buen lugar para hacer la solicitud es el
response.data.memes
) en una nueva propiedad de estado llamada allMemeImgs
.Cuando necesitamos cargar datos desde un punto final para usar en nuestro componente, un buen lugar para hacer la solicitud es el
componentDidMount()
mƩtodo del ciclo de vida. Tan pronto como se monte el componente, usamos la fetch()
función nativa para llamar a la URL proporcionada.componentDidMount() {
fetch("https://api.imgflip.com/get_memes")
}
Esto devuelve una promesa que convertimos en un objeto Javascript con el
.json()
mƩtodo.componentDidMount() {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
}
Luego obtenemos la respuesta que nos es Ćŗtil al extraer la matriz de memes
response.data
.componentDidMount() {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const { memes } = response.data
})
}
Ahora, guardamos los resultados en una nueva propiedad estatal llamada
allMemeImgs
. Para hacer esto, inicializamos allMemeImgs
como una matriz vacĆa.this.state = {
topText: '',
bottomText: '',
randomImg: 'http://i.imgflip.com/1bij.jpg',
allMemeImgs: []
};
Ahora, de vuelta
componentDidMount()
, establecemos el estado. Como no estamos interesados en cuƔl era el estado anterior, nos pusimos allMemeImgs
en memes.componentDidMount() {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const { memes } = response.data
this.setState({ allMemeImgs: memes })
})
}
Para asegurarnos de que funciona, tenemos
console.log
el primer elemento, que se parece a esto:
Aquà hay una descripción general de toda la
componentDidMount()
función.componentDidMount() { //ensure that data is fetched at the beginning
fetch("https://api.imgflip.com/get_memes") //call to URL
.then(response => response.json()) //turn promise into JS object
.then(response => {
const { memes } = response.data //pull memes array from response.data
console.log(memes[0]) // check data is present
this.setState({ allMemeImgs: memes }) // set allMemeImgs state
})
}
6. Crear el formulario de entrada
Ahora queremos crear un formulario que eventualmente permita al usuario ingresar los textos superior e inferior. Hacemos esto con una
<form>
etiqueta HTML y un simple <button>
que dice 'Gen'. Lo diseƱamos con el CSS proporcionado previamente.render() {
return (
<div>
<form className="meme-form">
<button>Gen</button>
</form>
</div>
)
}

7. Agregar campos de entrada al formulario

A continuación, depende de nosotros agregar los dos campos de entrada (uno para el texto superior y otro para el texto inferior). El formulario debe ser controlado, por lo que necesitaremos agregar todos los atributos necesarios para que eso funcione. Crearemos el
onChange
controlador mƔs tarde.
Creamos dos campos de entrada que tienen el tipo
text
y los atributos de nombre apropiados ( topText
y bottomText
). En lugar de usar etiquetas, usamos marcadores de posición: 'Texto superior' y 'Texto inferior'.
Por Ćŗltimo, para que esto sea una forma controlada , establecemos el valor como igual al valor actual en
state
con {this.state.topText}
y {this.state.bottomText}
.render() {
return (
<div>
<form className="meme-form">
<input
type="text"
name="topText"
placeholder="Top Text"
value={this.state.topText}
/>
<input
type="text"
name="bottomText"
placeholder="Bottom Text"
value={this.state.bottomText}
/>
<button>Gen</button>
</form>
</div>
)
}
8. Crear el controlador onChange.

Ahora, creamos el controlador onChange, que actualizarĆ” el estado correspondiente en cada cambio del campo de entrada.
Primero, creamos una
handleChange()
función que recibe un evento.handleChange(event) {
}
Ahora, establecemos los
onChange
dos campos de entrada en igual handleChange
.<form className='meme-form'>
<input
type='text'
name='topText'
placeholder='Top Text'
value={this.state.topText}
onChange={this.handleChange}
/>
<input
type='text'
name='bottomText'
placeholder='Bottom Text'
value={this.state.bottomText}
onChange={this.handleChange}
/>
<button>Gen</button>
</form>
Debemos recordar vincular el método en el constructor, un problema común para los desarrolladores de React.
constructor() {
super()
this.state = {
topText: "",
bottomText: "",
randomImg: "http://i.imgflip.com/1bij.jpg",
allMemeImgs: []
}
this.handleChange = this.handleChange.bind(this)
}
Para probar la nueva
handleChange()
función, agregamos un simple console.log
:handleChange(event) {
console.log("Working!")
}
Si estĆ” disparando correctamente, verĆ” algo como esto:


Ahora para completar la
handleChange()
función. Para hacer esto, queremos extraer las propiedades de nombre y valor de event.target para que podamos obtener el nombre del estado que debemos actualizar ( topText
o bottomText
) y el valor que se escribe en el cuadro.handleChange(event) {
const { name, value } = event.target
}
Ahora los utilizaremos para actualizar el estado. Como no estamos interesados en cuƔl era el estado anterior, solo podemos proporcionar un objeto en el que establezcamos
[name]
el valor escrito en el campo de entrada.handleChange(event) {
const {name, value} = event.target
this.setState({ [name]: value })
}
9. Mostrar una imagen de meme junto al texto superior e inferior
Ahora queremos que la aplicación muestre una imagen de meme junto con el texto superior e inferior. Insertamos una
<img>
etiqueta debajo de <form>
y establecemos la randomImg
que inicializamos como fuente mediante el uso src={this.state.randomImg}
. Luego agregamos dos <h2>
etiquetas que muestran el texto correspondiente que tambiƩn se guarda en estado. Todo esto estƔ envuelto en un div
estilo con la meme
clase proporcionada previamente .<div className='meme'>
<img src={this.state.randomImg} alt='' />
<h2 className='top'>{this.state.topText}</h2>
<h2 className='bottom'>{this.state.bottomText}</h2>
</div>
Ahora podemos probar la aplicación escribiendo en los cuadros de texto. Como el estado se establece correctamente en cada pulsación de tecla, el texto que se muestra en la imagen cambia cada vez que escribimos.

10. Mostrar una imagen aleatoria de meme junto al texto superior e inferior

Ahora, necesitamos crear un mƩtodo que muestre una imagen de meme que elija aleatoriamente de nuestra
Podemos dividir esta tarea en partes mƔs pequeƱas.
allMemeImgs
matriz cuando Gen
se haga clic en el botón. La propiedad de la imagen elegida en la matriz es .url
.Podemos dividir esta tarea en partes mƔs pequeƱas.
En primer lugar, configuramos los formularios
onSubmit
para que sean iguales al nombre de nuestro nuevo mƩtodo, al que llamaremos handleSubmit()
.<form className="meme-form" onSubmit={this.handleSubmit}>
Ahora creamos la
handleSubmit()
función encima de la render()
función. Necesitamos evitar DefaultDefault en el evento, de lo contrario, el método intentarÔ actualizar la pÔgina.handleSubmit(event) {
event.preventDefault()
}
TambiƩn necesitamos unirnos
handleSubmit()
a nuestro constructor()
.constructor() {
super()
this.state = {
topText: "",
bottomText: "",
randomImg: "http://i.imgflip.com/1bij.jpg",
allMemeImgs: []
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
Ahora, necesitamos obtener un nĆŗmero aleatorio, obtener el meme de ese Ćndice y establecerlo
randomImg
en el .url
elemento aleatorio.handleSubmit(event) {
event.preventDefault()
// get a random int (index in the array)
// get the meme from that index
// set `randomImg` to the `.url` of the random item I grabbed
}
Para obtener un nĆŗmero aleatorio, usamos
Math.floor(Math.random)
. Para asegurarnos de que sea uno de los Ćndices en nuestra allMemeImgs
matriz, multiplicamos por la longitud de la matriz.const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length);
Ahora nos ponemos
randMemeImg
a igual allMemeImgs
, con el Ćndice de allMemeImgs
como el randNum
que acabamos de obtener. Luego agregamos .url
al final de la misma.const randMemeImg = this.state.allMemeImgs[randNum].url;
Ahora, todo lo que tenemos que hacer es actualizar el estado actualizando la propiedad randomImg con
randMemeImg
.this.setState({ randomImg: randMemeImg });
Nuestra
handleSubmit()
función completa se ve asĆ:handleSubmit(event) {
event.preventDefault()
const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length)
const randMemeImg = this.state.allMemeImgs[randNum].url
this.setState({ randomImg: randMemeImg })
}
Generador de memes completado

Ahora hemos completado la aplicación del generador de memes y obtenemos una imagen diferente cada vez que presionamos el
Gen
botón, que luego se superpone con el texto que ingresamos.
Para avanzar en nuestro aprendizaje, podrĆamos jugar con código y ver si podemos mejorarlo o tratar de obtener imĆ”genes de una API diferente. Para algunas prĆ”cticas realmente pesadas, incluso podrĆamos eliminar todo el código e intentar construirlo nuevamente desde cero.
Felicitaciones por seguir el tutorial y aprender todas las habilidades utilizadas en este proyecto.
Y si estĆ”s listo para ello, ¡mira mi próximo curso avanzado , ya que te llevarĆ” a un nivel profesional en React!
No hay comentarios.:
Publicar un comentario