From a React course I'm taking:
I could implement most of the demands.
A life-demo can be seen here:
You have to click the "News" and "Photos" links on the right side for getting to the subpages.
Here's the code of the relevant components:
main.jsx
var React = require('react');
var ReactDOM = require('react-dom');
var Router = require('react-router').Router;
var Route = require('react-router').Route;
var Link = require('react-router').Link;
var CreateHashHistory = require('history/lib/createHashHistory');
var History = new CreateHashHistory({
queryKey: false
});
var Frame = require('./components/Frame.jsx');
var ArticleList = require('./components/ArticleList.jsx');
var Photos = require('./components/Photos.jsx');
ReactDOM.render(<Router history={ History }>
<Route path="/" component={ Frame }>
<Route path="/articles" component={ ArticleList }></Route>
<Route path="/photos" component={ Photos }></Route>
</Route>
</Router>, document.getElementById('app'));
Frame.jsx
var React = require('react');
var Link = require('react-router').Link;
var Frame = React.createClass({
render: function() {
return (
<div>
<div className="header">
<div className="row upper-header">
<h1 className="large-9 columns">
<Link to="/">Country News</Link>
</h1>
<div className="logos large-3 columns">
<a href="https://twitter.com/">
<img src="./imgs/twitter.png" alt="twitter_logo" />
</a>
<a href="https://de-de.facebook.com/">
<img src="./imgs/facebook.jpg" alt="facebook_logo" />
</a>
<a href="https://www.instagram.com/">
<img src="./imgs/instagram.jpg" alt="instagram_logo" />
</a>
<a href="https://de.linkedin.com/">
<img src="./imgs/linkedin.jpg" alt="linkedin_logo" />
</a>
<a href="mailto:[email protected]">
<img src="./imgs/mail_32.png" alt="mail_logo" />
</a>
</div>
</div>
<div className="row">
<p className="sub-title large-12 columns">Top stories in my country</p>
</div>
<div className="row links-subpages">
<div className="large-offset-10 large-1 columns">
<Link to="/articles">News</Link>
</div>
<div className="large-1 columns">
<Link to="/photos">Photos</Link>
</div>
</div>
</div>
<div className="content">
{ this.props.children }
</div>
</div>
);
}
});
module.exports = Frame;
Photos.jsx
var React = require('react');
var photoList = [ { urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: 'fe00fe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: '0034fe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: 'aa00fe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: '0077fe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: 'fe77fe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: '39abfe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: '2377fe' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: '5977ab' },
{ urlThumb: 'http://placehold.it/350x150/',
urlPhoto: 'http://placehold.it/700x300/',
color: '0022ab' } ];
var Photos = React.createClass({
render: function() {
var figureList = photoList.map(function(photo, i) {
return (
<div className="large-4 medium-2 columns end">
<figure>
<a href={ photo.urlPhoto + photo.color } className="popup">
<img src={ photo.urlThumb + photo.color } alt="illustration_photo"
className="thumbnail" title="Click to enlarge" />
</a>
</figure>
</div>);
});
return (
<div className="row photos">
{ figureList }
</div>
);
}
});
module.exports = Photos;
Article.jsx
var React = require('react');
var Article = React.createClass({
render: function() {
var key = 'id_' + this.props.id;
return (
<div className="row article">
<div className="left-col large-2 columns">
<figure>
<img src={ this.props.avatar } className="avatar-image"
alt="avatar_picture" />
</figure>
</div>
<div className="right-col large-10 columns">
<h1>{ this.props.title }</h1>
<h2>{ this.props.subtitle }</h2>
<p>{ this.props.text }</p>
<div>
<img src={ this.props.firstImage }
className="thumbnail" alt="thumbnail_image" />
<img src={ this.props.secondImage }
className="thumbnail" alt="thumbnail_image" />
</div>
<p>{ this.props.location }</p>
</div>
</div>
);
}
});
module.exports = Article;
ArticleList.jsx
$bodyColor: #cdcdcd;
$headerColor: blue;
$fontStack: Futura, Trebuchet MS, Arial, sans-serif;
$borderRadius: 4px;
* {
margin: 0;
padding: 0;
}
body {
background-color: $bodyColor;
font-family: $fontStack;
overflow: scroll;
}
ul.article-list {
margin-left: 0;
}
.header {
color: white;
font-weight: 700;
width: 100%;
background-color: $headerColor;
}
.thumbnail {
box-shadow: 2px 3px 6px grey;
border-radius:4px;
}
.article, .photos {
background-color: white;
margin-bottom: 20px;
}
.links-subpages {
padding: 10px;
}
.links-subpages a {
text-transform: uppercase;
color: white;
text-decoration: none;
padding: 5px;
}
.links-subpages a:hover {
background: 5px;
border: 1px solid white;
}
.sub-title {
font-size: 1.5rem;
margin-left: 15px;
}
.upper-header {
overflow: hidden;
display: flex;
}
.upper-header a {
display: inline-block;
text-decoration: none;
color: white;
}
a:hover {
cursor: pointer;
}
.links-subpages a:hover {
background-color: white;
color: $headerColor;
}
.logos {
display: flex;
justify-content: space-between;
align-items: center;
}
.logos a {
display: inline-block;
width: 34px;
height: 34px;
}
.logos a:hover {
opacity: 0.6;
}
.avatar-image {
border-radius: $borderRadius;
border: 1px solid $bodyColor;
padding: 5px;
}
The complete code (jQuery, Sass etc) can be seen on GitHub:
https://github.com/mizech/country-news
Is my implementation done in a proper way?
Where could I improve and where a weak points?
Moreover:
After publishing a prior exercise on CodeReview ( Building a multi-panel display with React and Bootstrap ) I was criticized (rightly) for writing all variables inside the render function. So that these variables are recreated every time the function is called.
I have tried to avoid variables within render() this time. But I don't know how to pass the data as props to ArticleList.jsx and Photos.jsx .
Within Frame.jsx the components are called via { this.props.children } . How can I pass the image-URLs and article-data via props from main.jsx or Frame.jsx?