React Dynamic Components - askbid-notes/notes-react GitHub Wiki
.props- Example 1
- Example 2 - Passing in
.props - Default Values
- Functions in JSX
- Input Multiple
.props
One more thing about props: they can be any data type! In our example, we pass a string as a prop. But we can pass a number, boolean, object, function, etc.
class BlogContent extends React.Component {
render() {
return (
<div>
{this.props.articleText}
</div>
)
}
}
class Comment extends React.Component {
render() {
return (
<div>
{this.props.commentText}
</div>
)
}
}
class BlogPost extends React.Component {
render() {
return (
<div>
<BlogContent articleText={"Dear Reader: Bjarne Stroustrup has the perfect lecture oration."}/>
<Comment commentText={"I agree with this statement. - Angela Merkel"}/>
<Comment commentText={"A universal truth. - Noam Chomsky"}/>
<Comment commentText={"Truth is singular. Its ‘versions’ are mistruths. - Sonmi-451"}/>
</div>
)
}
}Dynamic components are a core facet of React programming, and most of what we do as React programmers builds upon them.
results:
<div>
x
<div>
Dear Reader: Bjarne Stroustrup has the perfect lecture oration.
</div>
<div>
I agree with this statement. - Angela Merkel
</div>
<div>
A universal truth. - Noam Chomsky
</div>
<div>
Truth is singular. Its ‘versions’ are mistruths - Sonmi-451
</div>
</div>//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
//App.js
import React, { Component } from 'react';
import BlogPost from './BlogPost.js'
import ColorBox from './ColorBox.js'
class App extends Component {
render() {
return (
<div id="app">
<BlogPost />
<div id="seperator"></div>
<div className="wrapper">
<ColorBox opacity={1} />
</div>
</div>
)
}
}
export default App;
//BlogPost.js
import React, { Component } from 'react';
import Comment from './Comment'
export default class BlogPost extends Component {
render() {
const comments = [
"When we speak we are afraid.. - Audrey Lorde",
"I am no longer accepting... - Angela Davis",
"If you don't understand, ask ... - Chimamanda Ngozi Adichie"
]
return (
<div id="blog-post" className="wrapper">
Just like moons and like suns,<br/>
With the certainty of tides...<br/>
-Maya Angelou<br/>
<Comment commentText={comments[0]} />
<Comment commentText={comments[1]} />
<Comment commentText={comments[2]} />
</div>
);
}
}
//Comment.js
import React, { Component } from 'react';
export default class Comment extends Component {
render() {
return (
<div className='comment'>
{this.props.commentText}
</div>
)
}
}
//ColorBox.js
import React, { Component } from 'react';
export default class ColorBox extends Component {
state = {
todos: [
]
}
render() {
return (
<div className="color-box" style={{opacity: this.props.opacity}}>
{this.props.opacity >= 0.2 ? <ColorBox opacity={this.props.opacity - 0.1} /> : null}
</div>
)
}
}const title = "Mad Max"
const posterURL = "http://image.tmdb.org/t/p/w342/kqjL17yufvn9OVLyXYpvtyrFfak.jpg"
const genresArr = ["Action", "Adventure", "Science Fiction", "Thriller"]
<MovieCard title={title} posterSrc={posterURL} genres={genresArr} />
class MovieCard extends React.Component {
render() {
return (
<div className="movie-card">
<img src={this.props.posterSrc} alt={this.props.title} />
<h2>{this.props.title}</h2>
<small>{this.props.genres.join(', ')}</small>
</div>
)
}
}class MovieCard extends React.Component {
render() {
return (
<div className="movie-card">
<img src={this.props.posterSrc} alt={this.props.title} />
<h2>{this.props.title}</h2>
<small>{this.props.genres.join(', ')}</small>
</div>
)
}
}
MovieCard.defaultProps = {
posterSrc: 'http://i.imgur.com/bJw8ndW.png'
}Now, whenever we omit the posterSrc prop, or if it's undefined, the MovieCard component will use this default prop instead. This is more ideal than dealing with missing data say for instance in the parent component. We isolate responsibilities, the code is more organised.
A function called in JSX must be wrapped in curly braces and must return a single JSX element. That single JSX element, however, can contain other elements. So, for instance, the component below renders valid JSX [1]. There is an important exception to this: it is possible to return multiple JSX elements in an array. So instead of having to wrap the li elements above in a ul element, we could write [2]. because we can return arrays, we can use .map to map over data and return an array of elements [3].
import React from 'react';
class App extends React.Component {
//[1]
generateInnerJSX = () => {
return (
<ul>
<li>Hello</li>
<li>Goodbye</li>
</ul>
)
}
//[2]
generateInnerJSX = () => {
return [
<li>Hello</li>,
<li>Goodbye</li>
]
}
//[3]
generateInnerJSX = () => {
return LIST.map(item => <li>{item}<li>)
}
render() {
return (
<div>
{this.generateInnerJSX()}
</div>
)
}
}
export default App;//MovieShowcase.js
const movieData = [
{
title: 'Choux and Maru go to Istanbul',
IMDBRating: 3,
genres: ['cats', 'adventure', 'romance'],
poster: 'choux-maru-istanbul'
},
{
title: 'Choux and Maru',
IMDBRating: 4,
genres: ['cats', 'drama', 'romance'],
poster: 'choux-maru-part-1'
}]
export default class MovieShowcase extends Component {
generateMovieCards = () => movieData.map(obj => {return <MovieCard {...obj} />})
render() {
return (
<div id="movie-showcase">
{this.generateMovieCards()}
</div>
)
}
}
//MovieCard.js
import ttm from '../assets/poster-imgs/the-trash-man.png'
import defaultPoster from '../assets/poster-imgs/default.png'
import React, { Component } from 'react';
import CardFront from './CardFront.js';
import CardBack from './CardBack.js';
const posterMap = {
'the-trash-man': ttm,
'default': defaultPoster
}
export default class MovieCard extends Component {
render() {
return (
<div className="movie-card">
<CardFront poster={posterMap[this.props.poster]} />
<CardBack
title={this.props.title}
IMDBRating={this.props.IMDBRating}
genres={this.props.genres}
/>
</div>
);
}
}
MovieCard.defaultProps = {
title: 'Unknown',
IMDBRating: null,
genres: ['No Genre(s) Found'],
poster: 'default'
}
//CardFront.js
import React, { Component } from 'react';
export default class CardFront extends Component {
render() {
return (
<div className="card-front" style={{backgroundImage: `url(${this.props.poster})`}}>
</div>
)
}
}
//CardBack.js
import React, { Component } from 'react';
import zero from '../assets/stars/0-stars.png';
import one from '../assets/stars/1-stars.png';
import two from '../assets/stars/2-stars.png';
import three from '../assets/stars/3-stars.png';
import four from '../assets/stars/4-stars.png';
import five from '../assets/stars/5-stars.png';
const imgMapper = { 0: zero, 1: one, 2: two, 3: three, 4: four, 5: five };
export default class CardBack extends Component {
generateRatingElement = () => {
if (this.props.IMDBRating !== null) {
return <img src={imgMapper[this.props.IMDBRating]} alt="" />;
}
return <h4>No Rating Found</h4>;
};
render() {
return (
<div className="card-back">
<h3 className="title">{this.props.title}</h3>
<span />
{this.generateRatingElement()}
<span />
<h5 className="genres">{this.props.genres.join(', ')}</h5>
</div>
);
}
}