Creación de una aplicación de blogs con React, Parte 3: Agregar y mostrar publicación
Spanish (Español) translation by Valentino (you can also view the original English article)
En la parte anterior de esta serie de tutoriales, viste cómo implementar la función de registro e inicio de sesión. En esta parte del tutorial, implementarás la página de inicio del usuario y la funcionalidad para agregar y mostrar las publicaciones del blog.
Empezando
Comencemos clonando el código fuente de la primera parte del tutorial.
1 |
https://github.com/royagasthyan/ReactBlogApp-SignUp |
Una vez que se haya clonado el directorio, navega hasta el directorio del proyecto e instala las dependencias necesarias.
1 |
cd ReactBlogApp-SignUp
|
2 |
npm install
|
Inicie el servidor Node.js y tendrá la aplicación ejecutándose en http: // localhost: 7777 / index.html # /.
Creación de la página de inicio del usuario
Una vez que el usuario intenta iniciar sesión en la aplicación, debes validar las credenciales del usuario y, si es válido, crear una sesión. Para usar sesiones en una aplicación Node.js, debes instalar express-session usando Node Package Manager (npm).
1 |
npm install express-session --save |
Requiere la sesión rápida en el archivo app.js.
1 |
var session = require('express-session'); |
Para utilizar la sesión, debes establecer un secreto de sesión.
1 |
app.use(session({secret: 'my-secret'})); |
Ahora define una variable llamada sesiones en el ámbito global.
1 |
var sessions |
Asigna la variable de sesiones en el método / signin usando el parámetro de solicitud.
1 |
sessions=req.session; |
Con la variable de sesiones, mantienes el nombre de usuario que inició sesión en sesión.
1 |
sessions.username = user_name; |
Crea un archivo llamado home.html dentro de la carpeta html de la aplicación. Así es como se ve:
1 |
<!DOCTYPE html>
|
2 |
<html lang="en"> |
3 |
<head>
|
4 |
<meta charset="utf-8"> |
5 |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
6 |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
7 |
<meta name="description" content=""> |
8 |
<meta name="author" content=""> |
9 |
|
10 |
<title>React Blog App</title> |
11 |
<link href="bootstrap.min.css" rel="stylesheet"> |
12 |
<link href="jumbotron-narrow.css" rel="stylesheet"> |
13 |
|
14 |
|
15 |
</head>
|
16 |
|
17 |
<body>
|
18 |
|
19 |
<div class="container"> |
20 |
<div class="header clearfix"> |
21 |
<nav>
|
22 |
<ul class="nav nav-pills pull-right"> |
23 |
<li role="presentation" class="active"><a href="#">Home</a></li> |
24 |
<li role="presentation"><a href="#">Add</a></li> |
25 |
<li role="presentation"><a href="#">Logout</a></li> |
26 |
</ul>
|
27 |
</nav>
|
28 |
<h3 class="text-muted">React Blog App</h3> |
29 |
</div>
|
30 |
|
31 |
<div class="jumbotron"> |
32 |
<div class="list-group"> <a href="#" class="list-group-item active"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> <a href="#" class="list-group-item"> <h4 class="list-group-item-heading">List group item heading</h4> <p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> </a> </div> |
33 |
</div>
|
34 |
|
35 |
|
36 |
<footer class="footer"> |
37 |
<p>© 2016 Company, Inc.</p> |
38 |
</footer>
|
39 |
|
40 |
</div>
|
41 |
</body>
|
42 |
</html>
|
Crea una ruta rápida llamada / home que mostrará la página de inicio para un usuario válido.
1 |
app.get('/home', function (req, res) { |
2 |
if(sessions && sessions.username){ |
3 |
res.sendFile(__dirname + '/html/home.html'); |
4 |
}
|
5 |
else{ |
6 |
res.send('unauthorized'); |
7 |
}
|
8 |
})
|
Como se ve en el código anterior, cuando el usuario es redirigido a la ruta / home, si existen sesiones y session.username, se representa la página de inicio.
Modifica el método de inicio de sesión para enviar una respuesta de éxito en la validación de usuario correcta.
1 |
app.post('/signin', function (req, res) { |
2 |
sessions=req.session; |
3 |
var user_name=req.body.email; |
4 |
var password=req.body.password; |
5 |
user.validateSignIn(user_name,password,function(result){ |
6 |
if(result){ |
7 |
sessions.username = user_name; |
8 |
res.send('success'); |
9 |
}
|
10 |
});
|
11 |
})
|
La respuesta de éxito anterior se analiza en el lado de React y, si tiene éxito, se redirige al usuario a la ruta rápida / home. En el archivo main.jsx, dentro del componente Signin dentro del método signIn, modifica el código para redirigir a la página de inicio.
1 |
signIn(){ |
2 |
axios.post('/signin', { |
3 |
email: this.state.email, |
4 |
password: this.state.password |
5 |
})
|
6 |
.then(function (response) { |
7 |
if(response.data == 'success'){ |
8 |
window.location.assign('http://localhost:7777/home') |
9 |
}
|
10 |
})
|
11 |
.catch(function (error) { |
12 |
console.log(error); |
13 |
});
|
14 |
}
|
Guarda los cambios anteriores y reinicia el servidor Node. Inicia sesión con un nombre de usuario y contraseña válidos y serás redirigido a la página de inicio.



Modifica la visualización de la publicación del blog anterior en un componente React. Crea un archivo llamado home.jsx. Dentro del archivo home.jsx, crea un componente React llamado ShowPost que mostrará la lista de publicaciones del blog. Mueve el HTML estático dentro del método de renderización del componente React. Así es como se ve el componente ShowPost React:
1 |
class ShowPost extends React.Component { |
2 |
constructor(props) { |
3 |
super(props); |
4 |
}
|
5 |
|
6 |
render() { |
7 |
return ( |
8 |
<div className="list-group"> |
9 |
<a href="#" className="list-group-item active"> |
10 |
<h4 className="list-group-item-heading">List group item heading</h4> |
11 |
<p className="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> |
12 |
</a> |
13 |
<a href="#" className="list-group-item"> |
14 |
<h4 className="list-group-item-heading">List group item heading</h4> |
15 |
<p className="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> |
16 |
</a> |
17 |
<a href="#" className="list-group-item"> |
18 |
<h4 className="list-group-item-heading">List group item heading</h4> |
19 |
<p className="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p> |
20 |
</a> |
21 |
</div> |
22 |
)
|
23 |
}
|
24 |
}
|
Modifica la página home.html para incluir las bibliotecas React requeridas. Aquí está la página home.html modificada:
1 |
<!DOCTYPE html>
|
2 |
<html lang="en"> |
3 |
|
4 |
<head>
|
5 |
<meta charset="utf-8"> |
6 |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
7 |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
8 |
<meta name="description" content=""> |
9 |
<meta name="author" content=""> |
10 |
|
11 |
<title>React Blog App</title> |
12 |
<link href="bootstrap.min.css" rel="stylesheet"> |
13 |
<link href="jumbotron-narrow.css" rel="stylesheet"> |
14 |
<script src="https://fb.me/react-15.1.0.js"></script> |
15 |
<script src="https://fb.me/react-dom-15.1.0.js"></script> |
16 |
<script src="https://npmcdn.com/react-router@3.0.2/umd/ReactRouter.min.js"></script> |
17 |
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> |
18 |
<script src="https://unpkg.com/babel-core@5.8.38/browser.min.js"></script> |
19 |
|
20 |
</head>
|
21 |
|
22 |
<body>
|
23 |
|
24 |
<div class="container"> |
25 |
<div class="header clearfix"> |
26 |
<nav>
|
27 |
<ul class="nav nav-pills pull-right"> |
28 |
<li role="presentation" class="active"><a href="#">Home</a></li> |
29 |
<li role="presentation"><a href="#">Add</a></li> |
30 |
<li role="presentation"><a href="#">Logout</a></li> |
31 |
</ul>
|
32 |
</nav>
|
33 |
<h3 class="text-muted">React Blog App</h3> |
34 |
</div>
|
35 |
|
36 |
<div id="app" class="jumbotron"> |
37 |
|
38 |
</div>
|
39 |
|
40 |
|
41 |
<footer class="footer"> |
42 |
<p>© 2016 Company, Inc.</p> |
43 |
</footer>
|
44 |
|
45 |
</div>
|
46 |
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> |
47 |
<script type="text/babel" src="home.jsx"> |
48 |
</script>
|
49 |
</body>
|
50 |
|
51 |
</html>
|
Como se ve en el código HTML anterior, el contenedor div se ha denominado aplicación, dentro de la cual se mostrarán los componentes de React.
Guarda los cambios anteriores y reinicia el servidor de nodo. Inicia sesión en la aplicación del blog y, una vez en la página de inicio, tendrás el componente ShowPost React renderizado.
Ahora necesitas completar dinámicamente los valores en la lista de publicaciones. Antes de hacer eso, creemos una página para agregar una publicación. Al hacer clic en el hipervínculo Agregar anterior, debes mostrar la página para agregar la publicación del blog.
Agregar componente Post React
Creemos un componente Add post React para agregar las publicaciones del blog. Consistirá en un cuadro de entrada de título y un área de texto del tema. En home.jsx, crea un componente AddPost React para agregar publicaciones de blog. Así es como se ve el componente AddPost React:
1 |
class AddPost extends React.Component {
|
2 |
render() {
|
3 |
return ( |
4 |
<div className="col-md-5"> |
5 |
<div className="form-area"> |
6 |
<form role="form"> |
7 |
<br styles="clear:both" /> |
8 |
<div className="form-group"> |
9 |
<input type="text" className="form-control" id="title" name="title" placeholder="Title" required /> |
10 |
</div> |
11 |
|
12 |
<div className="form-group"> |
13 |
<textarea className="form-control" type="textarea" id="subject" placeholder="Subject" maxlength="140" rows="7"></textarea> |
14 |
</div> |
15 |
|
16 |
<button type="button" id="submit" name="submit" className="btn btn-primary pull-right">Add Post</button> |
17 |
</form> |
18 |
</div> |
19 |
</div> |
20 |
) |
21 |
} |
22 |
} |
Cuando el usuario ingresa el título y el asunto de la publicación, debes manejar los eventos de cambio de texto en el componente React. Agrega el siguiente controlador de eventos de cambio al componente AddPost React.
1 |
handleTitleChange(e){ |
2 |
this.setState({title:e.target.value}) |
3 |
}
|
4 |
handleSubjectChange(e){ |
5 |
this.setState({body:e.target.value}) |
6 |
}
|
Agrega el evento on change al HTML de renderizado AddPost.
1 |
<div className="form-group"> |
2 |
<input type="text" onChange={this.handleTitleChange} className="form-control" id="title" name="title" placeholder="Title" required /> |
3 |
</div>
|
4 |
|
5 |
<div className="form-group"> |
6 |
<textarea className="form-control" onChange={this.handleSubjectChange} type="textarea" id="subject" placeholder="Subject" maxlength="140" rows="7"></textarea> |
7 |
</div>
|
Vincula las variables de estado y los eventos en el método constructor de React.
1 |
constructor(props) { |
2 |
super(props); |
3 |
this.handleTitleChange = this.handleTitleChange.bind(this); |
4 |
this.handleSubjecChange = this.handleSubjectChange.bind(this); |
5 |
this.state = { |
6 |
title:'', |
7 |
subject:'' |
8 |
};
|
9 |
}
|
Cuando el usuario hace clic en el botón Agregar publicación, debes publicar el título y el asunto desde la interfaz de usuario de React en el back-end de Node.js para guardarlo en la base de datos de MongoDB. Crea un método llamado addPost en el componente AddPost React para publicar el título y el asunto en el controlador de solicitudes Node.js. Así es como se ve el método addPost en el componente AddPost React:
1 |
addPost(){ |
2 |
axios.post('/addPost', { |
3 |
title: this.state.title, |
4 |
subject: this.state.subject |
5 |
})
|
6 |
.then(function (response) { |
7 |
console.log('response from add post is ',response); |
8 |
hashHistory.push('/') |
9 |
})
|
10 |
.catch(function (error) { |
11 |
console.log(error); |
12 |
});
|
13 |
}
|
Como se ve en el código anterior, has utilizado axios para publicar los detalles de la publicación del blog en el servidor Node.js.
Ahora necesitas crear un módulo de publicación que se ocupará de agregar y obtener los detalles de la publicación. Crea un archivo llamado post.js en el directorio del proyecto. En el archivo post.js, exporta un método addPost que insertará los detalles de la publicación en la base de datos de MongoDB. Requiere MongoClient y crea el método addPost para insertar detalles de la publicación en la base de datos de MongoDB. Así es como se ve el archivo post.js:
1 |
var MongoClient = require('mongodb').MongoClient; |
2 |
var assert = require('assert'); |
3 |
var url = 'mongodb://localhost:27017/Blog'; |
4 |
|
5 |
module.exports = { |
6 |
addPost: function(title, subject, callback){ |
7 |
MongoClient.connect(url, function(err, db) { |
8 |
db.collection('post').insertOne( { |
9 |
"title": title, |
10 |
"subject": subject |
11 |
},function(err, result){ |
12 |
assert.equal(err, null); |
13 |
console.log("Saved the blog post details."); |
14 |
if(err == null){ |
15 |
callback(true) |
16 |
}
|
17 |
else{ |
18 |
callback(false) |
19 |
}
|
20 |
});
|
21 |
});
|
22 |
}
|
23 |
}
|
24 |
|
25 |
Como se ve en el código anterior, se conectó a la base de datos MongoDB usando el conector e insertó un registro. Una vez que se ejecutó la operación, verificaste el error, si lo hubiera, y devolviste el estado a la función de devolución de llamada.
Dentro del archivo app.js, crea un controlador de solicitudes llamado addPost que llamará al método addPost desde post.js. Así es como se ve:
1 |
app.post('/addpost', function (req, res) { |
2 |
var title = req.body.title; |
3 |
var subject = req.body.subject; |
4 |
post.addPost(title, subject ,function(result){ |
5 |
res.send(result); |
6 |
});
|
7 |
})
|
Guarda los cambios anteriores y reinicia el servidor Node.js. Inicia sesión en la aplicación, haz clic en el enlace Agregar e ingresa los detalles para agregar una publicación. Una vez hecho esto, haz clic en el botón Agregar publicación y los detalles deben guardarse en la base de datos de MongoDB.



Mostrar componente de reacción posterior
Primero debes obtener los detalles de la publicación guardada de MongoDB. Dentro del archivo post.js, crea un método llamado GetPost que obtendrá los detalles de la publicación. Así es como se ve:
1 |
getPost: function(callback){ |
2 |
MongoClient.connect(url, function(err, db){ |
3 |
db.collection('post', function (err, collection) { |
4 |
collection.find().toArray(function (err, list) { |
5 |
callback(list); |
6 |
});
|
7 |
});
|
8 |
})
|
9 |
}
|
El código anterior obtiene detalles de la colección MongoDB, los convierte en una lista y los envía de vuelta a la función de devolución de llamada. En el archivo home.jsx, dentro del componente ShowPost, obten los detalles de la publicación en el método componentDidMount. Así es como se ve:
1 |
componentDidMount(){ |
2 |
var self = this; |
3 |
|
4 |
axios.post('/getPost', { |
5 |
|
6 |
})
|
7 |
.then(function (response) { |
8 |
|
9 |
})
|
10 |
.catch(function (error) { |
11 |
console.log('error is ',error); |
12 |
});
|
13 |
}
|
El código anterior realiza una solicitud de publicación al método de servidor Node.js / getPost que llamará al método getPost en el archivo post.js. Aquí está el método / getPost en el archivo app.js.
1 |
app.post('/getpost', function (req, res) { |
2 |
post.getPost(function(result){ |
3 |
res.send(result); |
4 |
});
|
5 |
})
|
Una vez que se hayan obtenido los detalles de la publicación en la devolución de llamada de axios success, manten los detalles dentro de una variable de matriz de estado. Declara una variable llamada posts dentro del constructor ShowPost.
1 |
constructor(props) { |
2 |
super(props); |
3 |
this.state = { |
4 |
posts:[] |
5 |
};
|
6 |
}
|
En la devolución de llamada exitosa de la llamada axios ajax, establece la variable de estado como se muestra:
1 |
self.setState({posts:response.data}) |
Una vez que tengas los detalles de la publicación, debes crear dinámicamente el HTML requerido en el método de renderización del componente React. Así es como se ve:
1 |
render() { |
2 |
return ( |
3 |
<div className="list-group"> |
4 |
|
5 |
{
|
6 |
this.state.posts.map(function(post,index) { |
7 |
return <a href="#" key={index} className="list-group-item active"> |
8 |
<h4 className="list-group-item-heading">{post.title}</h4> |
9 |
<p className="list-group-item-text">{post.subject}</p> |
10 |
</a> |
11 |
})
|
12 |
}
|
13 |
|
14 |
</div> |
15 |
)
|
16 |
}
|
El código anterior itera la variable de estado de las publicaciones y crea el HTML de forma dinámica. Guarda los cambios anteriores y reinicia el servidor Node.js. Inicia sesión en la aplicación de blog y crea algunas publicaciones de blog usando el botón Agregar en la página de inicio. Una vez que se hayan agregado las publicaciones, se mostrarán en la página de inicio.



Envolviendolo
En este tutorial, viste cómo crear componentes de React para agregar y mostrar publicaciones de blog. En la siguiente parte de esta serie de tutoriales, aprenderás cómo agregar la funcionalidad para eliminar y actualizar las publicaciones del blog.
Déjame saber lo que piensas sobre este tutorial en la sección de comentarios a continuación. El código fuente de este tutorial está disponible en GitHub.



