A simple React project for studying.
Project examples are from Nomad Coder's
Set the project with create-react-app
(a.k.a CRA)
npx create-react-app movie-app
Remove unuse things except following code in App.js
file
App.js :
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div className="App">
<h1>Hello, React!</h1>
</div>
);
}
}
export default App;
Create Movies.jsx
file to make Movie component
import React, { Component } from 'react';
class Movie extends Component {
render() {
return (
<div>
<h1> This is Movie! </h1>
</div>
)
}
}
export default Movie;
And add <Movie>
component to App.js
import Movie from './Movie'; // import Movie Component
class App extends Component {
render() {
return (
<div className="App">
<Movie /> <!-- Add Movie Component -->
</div>
);
}
}
App :
const movieTItle = ['Matrix', 'Avengers'];
class App extends Component {
render() {
return (
<div className="App">
<Movie title={movieTitles[0]} />
<Movie title={movieTitles[1]} />
</div>
);
}
}
Component :
class Movie extends Component {
render() {
return (
<div>
<h1> {this.props.title} </h1>
</div>
)
}
}
App :
class App extends Component {
render() {
return (
<div className="App">
{movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index}/>
})}
</div>
);
}
}
Prop types can be checked by propType
in React
But React.propTypes
is deprecated after React 16
So, you need to install prop-types package
npm i prop-types -save
package.json :
"dependencies": {
"prop-types": "^15.6.2"
}
Movie.jsx :
import PropTypes from 'prop-types'; // add package
class Movie extends Component {
static propTypes = {
title: propTypes.string,
poster: propTypes.string
}
render (...)
}
propTypes
also can check if the prop is or not.
class Movie extends Component {
static propTypes = {
title: propTypes.string.isRequired, // title prop must be required
poster: propTypes.string // poster prop is optional
}
render (...)
}
will mount -> render -> did mount
But, componentWillMount
are deprecate React v16.3
New LifeCycle :
getDerivedStateFromProps
-> render
-> componentDidMount
class App extends Component {
state = {
greeting: 'Hello!'
}
componentWillMount() { // deprecated v16.3
console.log('will mount');
}
componentDidMount() {
console.log('did mount');
}
render() {
console.log('did rendered');
return (
<div className="App">
{this.state.greeting}
{movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index}/>
})}
</div>
);
}
}
Console print :
will mount
did rendered
did mount
Only when getDerivedStateFromProps
, you can change state even if you don't call setState
Let's change the state objects with adding the new item to movies array after 2 seconds.
Make movies
value state object's element.
Modify componentDidMount
function with setState
and setTimeout
.
class App extends Component {
state = {
greeting: 'Hello!',
movies : [
{
title : "Matrix",
poster: "https://posterimage_blah_blah"
},
{
title : "Star Wars",
poster: "https://posterimage_blah_blah2"
}
]
}
// New movie item will be add after 2000s
componentDidMount() {
setTimeout(() => {
this.setState({
movies: [
...this.state.movies, // This is Spread Syntax meaning all items of movies array
{
title: 'Coco',
poster: 'https://coco-movie-poster.jpg'
}
]
})
},2000);
}
Now we can use this.state.movies
instead of just movies
variable when renders.
render() {
return (
<div className="App">
{this.state.movies.map((movie, index) => {
return <Movie title={movie.title} poster={movie.poster} key={index}/>
})}
</div>
);
}
To simulate using API which data is supposed to save to state
"Smart" components have state.
"Dumb" components don't have state, only have props.
Class
which has states and Function
has only props.
But what Function
does is as same as Class
does.
Both return html code.
The Function
has an advantage that code is more concise,
but it is impossible updating state or other things like that.
- Class component which has state and props
// smart component
class MoviePoster extends Component {
render() {
return (
<img src={this.props.poster} />
)
}
}
- Function component which has only props
// dumb component
function MoviePoster({ poster }){
return (
<img src={poster} />
)
}
Let's change the Class component code to Function component code.
class Movie extends Component {
static propTypes = {
title: PropTypes.string.isRequired,
poster: PropTypes.string.isRequired
}
render() {
return (
<div>
<h1> {this.props.title} </h1>
<MoviePoster poster={this.props.poster}/>
</div>
)
}
}
to
function Movie ({title, poster}){
return (
<div>
<h1> {title} </h1>
<MoviePoster poster={poster}/>
</div>
)
}
Movie.propTypes = {
title: PropTypes.string.isRequired,
poster: PropTypes.string.isRequired
}
fetch
means to chatch something