React ๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป

Seoyul Kimยท2020๋…„ 8์›” 15์ผ
0

React

๋ชฉ๋ก ๋ณด๊ธฐ
1/5

React

  • Javascript Web Front-end Rendering ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ํ•˜๋‚˜๋กœ ๋ณดํ†ต Single Page Application Framework๊ฐ€ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๋ฐ˜๋ฉด์— React๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” Framework๊ฐ€ ์•„๋‹ˆ๋ผ View๋ฅผ ๋ Œ๋”๋ง ํ•˜๋Š” ๊ฒƒ์ด ์ฃผ ๊ธฐ๋Šฅ์ด๋ฉฐ ๋‚˜๋จธ์ง€ ๊ธฐํƒ€ ๊ธฐ๋Šฅ๋“ค์€ ์„œ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€์ ์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

Component

  • ๋ฆฌ์•กํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ๋ Œ๋”๋งํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ด ๋˜๋Š” ๋‹จ์œ„๋กœ React.Component๋ฅผ ์ƒ์†ํ•˜๋Š” ํด๋ž˜์Šค ํ˜•ํƒœ์˜ ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ์ˆ˜ ํ˜•ํƒœ์˜ ์ปดํฌ๋„ŒํŠธ ๋‘๊ฐ€์ง€ ํ˜•ํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๋ชฉ์ ์— ๋”ฐ๋ผ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๋ฆฌ์•กํŠธ๋Š” ์ž‘์€ ๋‹จ์œ„๋ถ€ํ„ฐ ํฐ ๋‹จ์œ„์˜ ์ปดํฌ๋„ŒํŠธ์˜ ์กฐํ•ฉ์œผ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ฐœ๋ฐœํ•˜๊ณ  ๊ฐ๊ฐ์„ ์ ์ ˆํžˆ ์กฐํ•ฉํ•˜์—ฌ ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ˜•ํƒœ๋กœ ๊ฐœ๋ฐœํ•œ๋‹ค.

State

  • ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ๋ฅผ state๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

Props

  • ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๋กœ๋ถ€ํ„ฐ parameter๋กœ ๋ฐ›์•„์˜ค๋Š” ๊ฐ’์„ ๋งํ•˜๋ฉฐ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.

๋ถˆ๋ณ€์„ฑ

  • ๋ฆฌ์•กํŠธ์—์„œ ๋ Œ๋”๋ง์„ ํ•  ๋•Œ ํŒ๋‹จํ•˜๋Š” ๋ฐฉ๋ฒ•์€ state๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ์ธ๋ฐ ๋ณ€๊ฒฝ ์ „/ํ›„ state๋ฅผ ์„œ๋กœ ๋น„๊ตํ•  ๋•Œ ๋ณต์žก๋„๊ฐ€ ๋†’์€ ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ ์ž์‹ ํ”„๋กœํผํ‹ฐ๊นŒ์ง€ ๋น„๊ตํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ํšจ์œจ์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ state์˜ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋–„ ๋ณ€๊ฒฝ๋œ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ๋ Œ๋”๋งํ•œ๋‹ค.

  • ๊ธฐ์กด state ๊ฐ’์„ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ธฐ์กด state ๊ฐ’์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ setState ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•˜์—ฌ ๋ณ€๊ฒฝํ•˜๋Š”๋ฐ ์ด๊ฒƒ์„ ๋ถˆ๋ณ€์„ฑ์„ ์šฐ์ง€ํ•œ๋‹ค๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.

์„ค์น˜ ๋ฐ ์ดˆ๊ธฐ์…‹ํŒ…

//์‚ฌ์ดํŠธ์—์„œ nodejs ์„ค์น˜
node -v //ํ™•์ธ

//npx ์„ค์น˜
npm install npx -g

//๋ฆฌ์•กํŠธ ์•ฑ ์ƒ์„ฑ
npx create-react-app movie_app
  • readme.md ์•ˆ์— ๋‚ด์šฉ์€ ์ง€์›Œ๋„ ๋œ๋‹ค.

  • yarn.lock, logo.svg, serviceworker, index.css, app.test.js, app.css๋Š” ์‚ญ์ œํ•ด๋„๋œ๋‹ค.

//index.js์—์„œ ๋‹ค์Œ์€ ์‚ญ์ œ ๊ฐ€๋Šฅํ•˜๋‹ค.

import './index.css';
import * as serviceWorker from './serviceWorker';

//React.DOM ์•„๋ž˜์˜ ๋ชจ๋“  ์ค„ ์‚ญ์ œ ๊ฐ€๋Šฅ

//app.js์—์„œ ์‚ญ์ œ
import logo from './logo.svg';
import './App.css';

//๋‹ค์Œ์ฒ˜๋Ÿผ empty div๋งŒ ๋‚จ๊ฒจ๋†“๊ณ  ์‚ญ์ œ
import React from 'react';

function App() {
  return <div className="App" />;
}

export default App;

JSX & PROPS

์ปดํฌ๋„ŒํŠธ๋ž€?

  • html์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๋ฐ˜๋ณตํ•ด์„œ ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ๋ฆฌ์•กํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ html์ฒ˜๋Ÿผ ์ž‘์„ฑํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋Ÿฌํ•œ javascript์™€ html์‚ฌ์ด์˜ ์กฐํ•ฉ์„ jsx๋ผ๊ณ  ํ•œ๋‹ค.

  • src ํด๋” ์•ˆ์— jsํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์ƒํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ•ญ์ƒ ํด๋” ์•ˆ์—์„œ react๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ฆฌ์•กํŠธ๋Š” jsx๊ฐ€ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ดํ•ดํ•˜์ง€ ๋ชปํ•œ๋‹ค.

  • ๋ฆฌ์•กํŠธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํ•˜๋‚˜์˜ ์ปดํฌ๋„ŒํŠธ๋งŒ์„ ๋ Œ๋”๋ง ํ•ด์•ผํ•œ๋‹ค.(์ดˆ๊ธฐ์…‹ํŒ…์‹œ app.js๋ฅผ ๋ ˆ๋”๋งํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์›๋ž˜ ๋งŒ๋“ค์–ด์ ธ์žˆ๋Š” app.js ํŒŒ์ผ ์•ˆ์— ์ƒˆ๋กœ์šด ์ปดํฌ๋„ŒํŠธ๋ฅผ importํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.)

  • ๋ฆฌ์•กํŠธ๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ํ‰ํ—˜ํ•œ ์ผ๋ฐ˜ html๋กœ ๋งŒ๋“ ๋‹ค.

  • ์ปดํฌ๋„ŒํŠธ์— ์ •๋ณด๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ์—์„œ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๋กœ ์ •๋ณด๋ฅผ ๋ณด๋‚ด๋Š” ๋ฐฉ๋ฒ•

import React from "react";

function Food(props){
	console.log(props.name) // kimchi
	return <h1>I like Potato</h1>;
}

function App() {
	return (
    	<div>
         	<h1>Hello</h1>
            <Food name = "kimchi" />
        </div>
    )
}
  • food component์— kimchi๋ผ๋Š” value๋กœ prop(property) name์„ ์ค€๋‹ค.

  • string, boolean, array, number, true๋กœ ๋‹ค์–‘ํ•˜๊ฒŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ food component๋กœ ์ •๋ณด๋ฅผ ๋ณด๋‚ด๋ ค๊ณ  ํ•˜๋ฉด react๋Š” ์ด ๋ชจ๋“  ์†์„ฑ์„ ๊ฐ€์ ธ์™€ food function component์˜ ์ธ์ž๋กœ ๋„ฃ๋Š”๋‹ค.

function Food({name, picture}){
	console.log(props.name) // kimchi
	return <h1>I like {name}</h1>;
}
  • props์˜ ๋ชจ๋“  object๋ฅผ ์—ด์–ด์„œ ์†์„ฑ์„ ๊บผ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

  • jsx + props์˜ ํž˜์œผ๋กœ ์ปดํฌ๋„ŒํŠธ์— ์ •๋ณด๋ฅผ ๋ฐ›์•„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • jsx = HTML + JavaScript

์ปดํฌ๋„ŒํŠธ๋Š” ๋Œ€๋ฌธ์ž๋กœ ์‹œ์ž‘ํ•ด์•ผํ•˜๋ฉฐ, props๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •๋ณด๋ฅผ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

Dynamic Component Generation

function Food({name, picture}){
	return <div>
    	<h2>I like {name}</h2>
        <:img src={picture} />
    </div>;
}

const foodILike = [
	{
    	name : "kimchi",
        image : "http://aeriskitchen.com..."
    },
    {
    	name : "samgyepsal",
        image : "http://aeriskitchen.com..."
    },
    {
    	name : "bibimbap",
        image : "http://aeriskitchen.com..."
    },
    {
    	name : "donkasu",
        image : "http://aeriskitchen.com..."
    },
    {
    	name : "kimbap",
        image : "http://aeriskitchen.com..."
    }

];

function App() {
	return (
    	<div> 
            {foodILike.map(dish => <Food name = {dish.name} picture={dish.image} />)}
    )
}

const friends = ["dal", "mark", "lynn"];
friends.map(current => {
	console.log(current);
    return 0 
})
  • map : array์˜ ๊ฐ ์•„์ดํ…œ์—์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” array๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜์ด๋ฉฐ ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ–๋Š” array๋ฅผ ์ค€๋‹ค. (array๋กœ๋ถ€ํ„ฐ array๋ฅผ ์ค€๋‹ค.)

  • map์€ function์„ ์ทจํ•ด์„œ ๊ทธ function์„ array์˜ ๊ฐ item์— ์ ์šฉํ•œ๋‹ค.

map Recap

function renderFood(dish) {
	console.log(dish);
    return <Food name={dish.name} picture={dish.image} / >
}

function App() {
	return (
    	<div>{foodILike.map(renderFood)}</div>
    )
}
  • ๋ชจ๋“  ๋ฆฌ์•กํŠธ์˜ ์š”์†Œ๋“ค์€ ์œ ์ผํ•ด์•ผํ•˜๋ฉฐ ์ด๋“ค์„ ๋ฆฌ์ŠคํŠธ ์•ˆ์œผ๋กœ ์ง‘์–ด๋„ฃ์„ ๋•Œ ์œ ์ผ์„ฑ์„ ์žƒ๋Š”๋‹ค.(์š”์†Œ์— id๋ฅผ ์ค€๋‹ค.)
const foodILike = [
	{
    	id : 1,
    	name : "kimchi",
        image : "http://aeriskitchen.com..."
    },
    {
    	id : 2,
    	name : "samgyepsal",
        image : "http://aeriskitchen.com..."
    }
];

function Food({name, picture}){
	return <div>
    	<h2>I like {name}</h2>
        <img src={picture} alt={name}/>
    </div>;
}

function App() {
	return (
    	<div> 
            {foodILike.map(dish =>( 
            <Food key={dish.id} name = {dish.name} picture={dish.image} />))}
    )
}

Protection with PropTypes

  • key prop์€ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์œผ๋ฉฐ ๊ธฐ๋ณธ์ ์œผ๋กœ react๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.

  • ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” props๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” props ์ธ์ง€ ์ฒดํฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•˜๋‹ค.

// ์ „๋‹ฌ๋ฐ›์€ props๊ฐ€ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” props์ธ์ง€ ํ™•์ธํ•œ๋‹ค.
npm i prop-types

import PropTypes from "prop-types";

function Food({name, picture, rating}){
	return <div>
    	<h2>I like {name}</h2>
        <h4>{rating}/5.0</h4>
        <img src={picture} alt={name}/>
    </div>;
}
Food.propTypes = {
	name: PropTypes.string.isRequired,  
    picture: PropTypes.string.isRequired,
    rating: PropTypes.number
}

const foodILike = [
	{
    	id : 1,
    	name : "kimchi",
        image : "http://aeriskitchen.com...",
        rating : 5
    },
    {
    	id : 2,
    	name : "samgyepsal",
        image : "http://aeriskitchen.com...",
        rating : 4.9
    }
];

function App() {
	return (
    	<div> 
            {foodILike.map(dish =>( 
            <Food 
            	key={dish.id} 
                name = {dish.name} 
                picture={dish.image}
                rating = {dish.rating}
            />))}
    )
}

State

class components and state

  • ๋ณดํ†ต ๋™์  ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์ž‘์—…ํ•  ๋•Œ ๋งŒ๋“ค์–ด์ ธ ๋ณ€ํ•˜๋Š” ๋ฐ์ดํ„ฐ, ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ, ๊ทธ๋ฆฌ๊ณ  ์ƒ๊ฒจ๋‚˜๊ณ  ์‚ฌ๋ฆฌ์ง€๊ฑฐ๋‚˜ ๋˜๋Š” ๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ ๋“ฑ์˜ ์ข…๋ฅ˜๋ฅผ dynamic data๋ผ๊ณ  ํ•˜๋ฉฐ, ์ด๋Ÿด ๊ฒฝ์šฐ state๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
//APP ์€ React component
class App extend React.Compponent{
	state = {
    	count: 0
    };
     add = () => {
    	console.log("add");
        //this.state.count = 1;  ์ด๋ ‡๊ฒŒ ์ง์ ‘ state๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
        this.setState({count: this.state.count+1});// ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•
        //state๋ฅผ setํ•  ๋•Œ react์—์„œ ์™ธ๋ถ€์˜ ์ƒํƒœ์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
        this.setState(current => ({count : current.count +1}));
    };
    
    minums =() => {
    	console.log("minus");
        this.setState({count: this.state.count-1})
    };
	render(){
      return(
    	<div>
    	<h1>The number is: {this.state.count}</h1>
        <button onClick={this.add}>Add</button>
        <button onClick={this.minus}>Minus</button>
        </div>
       );
    }
}
  • React component๋Š” ๋งŽ์€ ๊ฒƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ๊ทธ์ค‘ ํ•˜๋‚˜๊ฐ€ state์ด๋‹ค. ๋งค๋ฒˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค ๋ชจ๋“  ๊ฒƒ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด extend ํ•œ๋‹ค.

  • react class component์—์„œ extendํ•˜์—ฌ App component๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.(App component๋Š” React component)

  • class react component๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— return ์„ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š๋‹ค. render method๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ react component์—์„œ ํ™•์žฅํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— app component ์•ˆ์— ์žˆ๋‹ค.

  • Function component๋Š” ํ•จ์ˆ˜์ด๋ฉฐ ๋ฌด์–ธ๊ฐ€๋ฅผ return ํ•˜๊ณ  screen์— ํ‘œ์‹œ๋œ๋‹ค. class component๋Š” class ์ด์ง€๋งŒ react component๋กœ๋ถ€ํ„ฐ ํ™•์žฅ๋˜๋ฉฐ screen์— ํ‘œ์‹œ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  react๋Š” ์ž๋™์ ์œผ๋กœ ๋ชจ๋“  class component์˜ render method๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

  • state๋Š” object์ด๋ฉฐ component์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์„ ๊ณต๊ฐ„์ด ์žˆ๊ณ  ์ด ๋ฐ์ดํ„ฐ๋Š” ๋ณ€ํ•œ๋‹ค.

  • class์ด๊ธฐ ๋•Œ๋ฌธ์— this.state.count๋กœ ์‚ฌ์šฉ

  • ๋งค๋ฒˆ state์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ react๊ฐ€ render function์„ ํ˜ธ์ถœํ•ด์„œ ๋ฐ”๊ฟ”์ฃผ๊ธธ ์›ํ•œ๋‹ค๋ฉด setState function์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • state๋Š” object์ด๊ธฐ ๋•Œ๋ฌธ์— setState๋Š” ์ƒˆ๋กœ์šด state๋ฅผ ๋ฐ›์•„์•ผํ•œ๋‹ค.

  • setState๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด state๋ฅผ refreshํ•˜๋ฉฐ ์ƒˆ๋กœ์šด state์™€ ํ•จ๊ป˜ render function์„ ํ˜ธ์ถœํ•œ๋‹ค.

Component Life Cycle

  • life cycle method๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ react๊ฐ€ component๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์—†์• ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

Mounting

  • constructor() : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ class๋ฅผ ๋งŒ๋“ค ๋•Œ ํ˜ธ์ถœ๋œ๋‹ค.
class App extend React.Compponent{
	constructor(props){
    	super(props);
    	console.log("hello");
    }
	state = {
    	count: 0
    };
     add = () => {
    	console.log("add");
        //this.state.count = 1;  ์ด๋ ‡๊ฒŒ ์ง์ ‘ state๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค.
        this.setState({count: this.state.count+1});// ์ถ”์ฒœํ•˜์ง€ ์•Š๋Š” ๋ฐฉ๋ฒ•
        //state๋ฅผ setํ•  ๋•Œ react์—์„œ ์™ธ๋ถ€์˜ ์ƒํƒœ์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.
        this.setState(current => ({count : current.count +1}));
    };
    
    minums =() => {
    	console.log("minus");
        this.setState({count: this.state.count-1})
    };
    componentDidMount() {
    	console.log("component rendered");
    }
    componentDidUpdate() {
    	console.lof("i just updated"); 
    }
	render(){
      console.log("render")
      return(
    	<div>
    	<h1>The number is: {this.state.count}</h1>
        <button onClick={this.add}>Add</button>
        <button onClick={this.minus}>Minus</button>
        </div>
       );
    }
}

-> hello
	render
  • static getDerivedStateFromProps()

  • render()

  • componentDidMount() : component๊ฐ€ ์ฒ˜์Œ render ๋œ๊ฒƒ์„ ์•Œ๋ ค์ค€๋‹ค.

Updating

  • setState๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค ๋ฐœ์ƒํ•œ๋‹ค.

  • static getDerivedStateFromProps()

  • shouldComponentUdate() : ์ปดํฌ๋„ŒํŠธ๋ฅผ ์—…๋ฐ์ดํŠธ ํ• ์ง€ ๋ง์ง€ ๊ฒฐ์ •

  • render()

  • getSnapshopBeforeUpdate()

  • componentDidUpdate()

Unmounting

  • ํŽ˜์ด์ง€๋ฅผ ๋ฐ”๊พธ๊ฑฐ๋‚˜ state๋ฅผ ์‚ฌ์šฉํ•ด์„œ component๋ฅผ ๊ต์ฒดํ•˜๋Š” ๊ฒฝ์šฐ

  • componentWillUnmount()

import React from "react";

class App extends React.Component {
	state = {
    	isLoading : true,
        movies : []
    }
    componentDidMount() {
    	setTimeout(() => {
        	this.setState({isLoading : false });
        }, 6000);
    }
	render() {
    	const {isLoading} = this.state;//return์˜ isLoading์—์„œ this.state.isLoading์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ํ•ญ์ƒ this.state๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    	return <div>{isLoading ? "Loading" : "We are ready"}</div>;
    }
}

export default App;
  • render๋ฅผ ํ•˜๋ฉด ๊ฐ€์žฅ ์ฒ˜์Œ์— ํ˜ธ์ถœ๋˜๋Š” life cycle method๋Š” componentDidMount() ์ด๋‹ค.(component๊ฐ€ mount ๋˜์ž๋งˆ์ž ํ˜ธ์ถœ๋œ๋‹ค.)

Fetch data

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ fetchํ•˜๋Š” ๋ฐฉ๋ฒ•์€ fetch()๋ฅผ ์ด์šฉํ• ์ˆ˜๋„ ์žˆ์ง€๋งŒ axios๋กœ๋„ ๊ฐ€๋Šฅํ•˜๋ฉฐ fetch์œ„์— ์žˆ๋Š” ์ž‘์€ ๋ ˆ์ด์–ด์™€ ๊ฐ™๋‹ค.
npm i axios

import axios from "axios";
import React from "react";

class App extends React.Component {
	state = {
    	isLoading : true,
        movies : []
    }
    componentDidMount() {
    	const movies = axios.get("https://yts-proxy.now.sh/list_movies.json");
    }
	render() {
    	const {isLoading} = this.state;//return์˜ isLoading์—์„œ this.state.isLoading์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ํ•ญ์ƒ this.state๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    	return <div>{isLoading ? "Loading" : "We are ready"}</div>;
    }
}

export default App;
  • axios.get()์€ ๋Š๋ฆด ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๊ฒŒ componentDidMount ํ•จ์ˆ˜๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ์•ฝ๊ฐ„ ์‹œ๊ฐ„์ด๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ๊ณ  ๊ธฐ๋‹ค๋ ค์•ผํ•œ๋‹ค.
    async componentDidMount() {
    	const movies = axios.get("https://yts-proxy.now.sh/list_movies.json");
    }
    
    or
    
    getMovies = async() => {
       	const movies = await axios.get("https://yts-proxy.now.sh/list_movies.json");
    }
    componentDidMount() {
		this.getMovies();
    }
  • ํ•จ์ˆ˜๊ฐ€ ๋น„๋™๊ธฐ์ด๋ฉฐ ๊ทธ๊ฒƒ์„ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด async, ๊ธฐ๋‹ค๋ ค์•ผํ•  ๊ฒƒ์„ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ await์„ ์‚ฌ์šฉํ•œ๋‹ค.

rendering

    getMovies = async() => {
       	const movies = await axios.get("https://yts-proxy.now.sh/list_movies.json");
        console.log(movies);
        //์œ„์˜ console.log๋กœ ํ™•์ธ ํ›„ ์ ‘๊ทผ
        console.log(movies.data.data.movies)
    }
    componentDidMount() {
		this.getMovies();
    }
    
    or
    
        getMovies = async() => {
       	const {data: {data: {movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json");
        console.log(movies);
    }
    componentDidMount() {
		this.getMovies();
    }
  • ๋ฐ์ดํ„ฐ ํ™•์ธ ํ›„ state์— ์ง‘์–ด๋„ฃ๋Š”๋‹ค.
state = {
    	isLoading : true,
        movies : []
    }
getMovies = async() => {
       	const {data: {data: {movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json?sort_by=rating");\
        //state์˜ movies๋Š” axiosd์˜ movies
        //this.setState({movies : movies})
        //์œ„์™€ ๊ฐ™์€ ์˜๋ฏธ๋กœ ์ตœ์‹ ๋ฒ„์ „์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
        this.setState({movies, isLoading : false});
        
    }
    componentDidMount() {
		this.getMovies();
    }
  • movie๋ฅผ renderingํ•˜๊ธฐ ์œ„ํ•ด์„œ movies.js ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค
import React from "react";
import PropTypes from "prop-types";

function Movie{id, title, poster}) {
	return<h1>{movie}</h1>
}

Movie.propTypes = {
	id : PropTypes.number.isRequired,
    title : PropTypes.string.isRequired,
    poster : PropTypes.string.isRequired,
	
}

export default Movie;
  • ์ปดํฌ๋„ŒํŠธ์— state๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ class๊ฐ€ ์•„๋‹Œ ํ•จ์ˆ˜ํ˜•์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • ์ด ํŒŒ์ผ์„ renderํ•˜๊ธฐ ์œ„ํ•ด์„œ app.js์— ์ถ”๊ฐ€ํ•œ๋‹ค.

import Movie from "./Movie";

class App extends React.Component {
	state = {
    	isLoading : true,
        movies : []
    }
    getMovies = async() => {
       	const {data: {data: {movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json?sort_by=rating");
        this.setState({movies, isLoading : false});
        
    }
    componentDidMount() {
		this.getMovies();
    }
	render() {
    	const {isLoading, movies} = this.state;//return์˜ isLoading์—์„œ this.state.isLoading์œผ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ ํ•ญ์ƒ this.state๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    	return <div>{isLoading ? "Loading" : movies.map(movie) => {
        return <Movie key = {movie.id}id={movie.id} title={movie.title} poster={movie.medium_cover_image} />
        }}</div>;
    }
}

export default App;

Deploying to Github Pages

npm i gh-pages
  • gh-pages๋Š” ์›น์‚ฌ์ดํŠธ๋ฅผ github์˜ githyb page ๋„๋ฉ”์ธ์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•ด์ค€๋‹ค.
//package.json ๋งˆ์ง€๋ง‰์— ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
"homepage" : "https://{github username}.github.io/{name of project in guthub}"
//scripts์— deploy๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
	"deploy" : "gh-pages -d build"
    "predeploy" : "npm run build"
    
 npm run build
 
 npm run deploy

Routing

react-router-dom

npm install react-router-dom
  • url์„ ๊ฐ€์ ธ๋‹ค๊ฐ€ ํ™•์ธํ•˜๊ณ  ์šฐ๋ฆฌ๊ฐ€ ๋ผ์šฐํ„ฐ์— ๋ช…๋ นํ•˜๋Š” ๊ฒƒ์— ๋”ฐ๋ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.

  • ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ url์„ ๊ฐ€์ ธ์™€์„œ ๋ผ์šฐํ„ฐ์— ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ๊ณผ ๋น„๊ตํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งค์น˜๊ฐ€ ๋œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณด์—ฌ์ค€๋‹ค.(๋‘๊ฐœ์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.)

//components/Navigation.js

import react from "React";

fuction Navigation() {
    return (
        <div>
            <a href="/">Home</a>
            <a href="/about">About</a>
        </div>
    );
}

export default Navigation;
  • ์ƒˆ๋กœ๊ณ ์นจํ•˜์—ฌ ํŽ˜์ด์ง€๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค.
//app.js
import {HashRouter, Route} from "react-router-dom";
import Navigation from "./components/Navigation"

function App(){
  return (
    <HashRouter>
      <Navigation />
      <Route path="/home" exact={true} component={Home} />
      <Route path="/about" component={About} />
    </HashRouter>
  );
}
  • BrowserRouter ํ˜น์€ HashRouter๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, github-pages์—์„œ๋Š” HashRouter๊ฐ€ ์„ค์ •ํ•˜๊ธฐ ๋” ํŽธํ•˜๋‹ค.
<BrowserRouter />: HTML5 ํžˆ์Šคํ† ๋ฆฌ API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฃผ์†Œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ผ์šฐํ„ฐ(ํ•ด์‰ฌ๋ฑ… ๋ชจ๋“œ ์‚ฌ์šฉ ์•ˆํ•จ)
<Route />: ์š”์ฒญ ๊ฒฝ๋กœ์™€ ๋ Œ๋”๋งํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ์„ค์ •ํ•œ๋‹ค
<Switch />: ํ•˜์œ„์— ๋ผ์šฐํ„ฐ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•œ๋‹ค
<Redirect />: ์š”์ฒญ ๊ฒฝ๋กœ๋ฅผ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ํ•œ๋‹ค

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜์—ฌ ๊ทœ์น™์„ ๋ฒ—์–ด๋‚ฌ์„ ๊ฒฝ์šฐ(์ •ํ•ด์ง„ ์ปดํฌ๋„ŒํŠธ ๊ฒฝ๋กœ๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ค์ง€ ์•Š์„ ๊ฒฝ์šฐ) ๋ฃจํŠธ ์š”์ฒญ์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰์…˜ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

<Redirect path="*" to="/" />
    </Switch>

Event

onClick

<h1><a href="/" onClick={function(e){
		e.preventDefault();//ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ํŽ˜์ด์ง€๊ฐ€ reload๋˜๋Š” ๊ฒƒ์„ ๋ง‰์•„์ค€๋‹ค.
	}}>

[TIL] React
HTML DOM Events
React์—์„œ Mobx ๊ฒฝํ—˜๊ธฐ (Redux์™€ ๋น„๊ต๊ธฐ)
๋ˆ„๊ตฌ๋“ ์ง€ ํ•˜๋Š” ๋ฆฌ์•กํŠธ 4ํŽธ: props ์™€ state
๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ ์‚ฌ์šฉํ•˜๊ธฐ (ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋ฒ„์ „)
๋ฆฌ์•กํŠธ Styled Componets - 2ํŽธ
Strict ๋ชจ๋“œ
ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด(Template Literal)๊ณผ ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ(styled-component)
๋ฆฌ์•กํŠธ ๊ณต๋ถ€! ์Šคํƒ€์ผ๋“œ ์ปดํฌ๋„ŒํŠธ
tyled-Components๋ฅผ ์ด์šฉํ•œ React ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ๋ง
[react package] styled-components์—์„œ global style ์ ์šฉํ•˜๊ธฐ, css reset
[React] Styled Components ์‚ฌ์šฉ๋ฒ•
default export์™€ named export ์ฐจ์ด์ 
React Router๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆํ•˜๊ธฐ (๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ)
React ์ ์šฉ ๊ฐ€์ด๋“œ - React ์ž‘๋™ ๋ฐฉ๋ฒ•
Axios ๋Ÿฌ๋‹๊ฐ€์ด๋“œ
5 Ways to animate a React app.
[๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ ] 4์žฅ - ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง
styled-component + react-transition-group = very simple Transition

0๊ฐœ์˜ ๋Œ“๊ธ€