React

Monday, August 24, 2020

생활코딩 React강의

개요

Component 작성으로 얻는 것

  1. 가독성
  2. 재사용성
  3. 유지보수

개발환경

  1. nodejs 설치

    • cmd에서 npm -v 를 입력하여 설치확인
  2. create-react-app 설치

    • cmd 상에서 (실습용)
    npm install -g create-react-app@2.1.8
    

    (실제 사용시 최신버전을 쓸때 npm대신 npx사용)

  3. 세팅

    • 폴더 생성
    • cmd에서 폴더로 이동후
    create-react-app .
    
    • 웹앱 실행
    npm run start
    
  4. 배포

    • 브라우저 reload에 우클릭해서 ‘Empty Cache and Hard Reload’해서 보면 1.7M를 다운로드한다.
    • 개발모드에서는
    npm run start
    
    • 빌드할때는
    npm run build
    

    이렇게 하면 build 폴더가 생기고 살펴보면 공백이 없고 폴더내 html 파일 용량이 줄어든다.

    • 실제 서비스 할때는 buil 폴더 안의 파일을 사용한다.
    • serve 한번만 실행시킬 웹서버 실행
    npx serve -s build
    
  5. Component 생성

class Subject extends Component {
  render(){
    return(
      <header>
        <h1>WEB</h1>
        world wide web!
      </header>
    );
  }
}

class App extends Component {
  render() {
    return (
      <div className="App">
        <Subject></Subject>
      </div>
    );
  }
}
- Subject라는 Class를 만든다.
- Class 안에서 function 단어 생략
- JS 문법과 다른 JXS
- Component는 정리정돈의 개념으로 복잡도를 낮춤
class Subject extends Component {
  render(){
    return(
      <header>
        <h1>{this.props.title}</h1>
        {this.props.sub}
      </header>
    );
    
  }
}
class App extends Component {
  render() {
    return (
      <div className="App">
        <Subject title='WEB' sub="world wide web!"></Subject>
        <TOC></TOC>
        <Content></Content>
      </div>
    );
  }
}
- props 이용하여 사용자 정의 태그
  1. 크롬 확장 프로그램

    • React Developer Tools을 이용하여 브라우저에서 리액트로 상태 확인 가능
  2. Component 파일로 분리하기

import React, { Component } from 'react';

class TOC extends Component {
    render(){
      return (
        <nav>
              <ul>
                  <li><a href="1.html">HTML</a></li>
                  <li><a href="2.html">CSS</a></li>
                  <li><a href="3.html">HTML</a></li>
              </ul>
        </nav>
      );
    }
  }
export default TOC;
- 새 파일에 Component를 복사하고 Import하고 다른 파일에서 사용할 수 있게 export 구문을 작성한다.
import TOC from "./components/TOC";
- 분리된 Component를 사용할 파일에서 import한다.
  1. state
  • React에서 Component를 외부에서 조작할 떄는 props를, 내부적으로 상태를 관리할 때는 state를 사용한다.
  • props are read-only, state can be modified
constructor(props){
  super(props);
}
  • Component를 실행할 때 Props를 초기화 시켜주는 코드
this.state = {
    subject:{title:'WEB', sub:'World Wide Web!'}
  }
  • state에 초기값 지정
<Subject 
title={this.state.subject.title} 
sub={this.state.subject.sub}>
</Subject>
  • title과 sub를 state에서 가져온다.
  • 내부적으로 사용하고 외부에 노출하지 않으므로 사용성을 높인다.
  • 반복문일때 key 값을 지정해주지 않으면 에러 발생
  1. event
  • code에 debugger를 넣으면 브라우저에서 그부분에서 실행이 멈춘다.
function(e){
  e.preventDefault();
}
  • event들의 기본적인 동작 방법을 못하게 할때는 preventDefault()를 사용한다.
<h1><a href="/" onClick={function(e){
  console.log(e);
  e.preventDefault();
  //this.state.mode = 'welcome';
  this.setState({
    mode:'welcome'
  });
}.bind(this)}>{this.state.subject.title}</a></h1>
  • 함수안에서 this를 사용하면 에러가 뜨므로 .bind(this)를 넣어준다.
functionA.bind(B)
  • bind는 어떤 함수(functionA)내에서 this의 값(B)을 지정해준다.
  • state 변경은 this.setState로 한다.
  • component에서 state가 정해져 있으므로 함수의 형태로 바꿔줘야한다.
  1. Create
<form action="/create_process" method="post"
  onSubmit={function(e){
    e.preventDefault();
  }.bind(this)}
>
- form tag에 onSubmit을 이용
//this.state.contents.push(
//  {id:this.max_content_id, title:_title, desc:_desc});
var _contents = this.state.contents.concat(
  {id:this.max_content_id, title:_title, desc:_desc}
)
this.setState({
  contents:_contents
  • push는 원본 배열을 변경하는것이고 concat은 다른 변수에 원본에 추가한 배열로 설정하므로 원본은 변하지 않는다.
shouldComponentUpdate(newProps, newState){
    console.log('==>TOC render shouldComponentUpdate'
    ,newProps.data
    ,this.props.data
    );
    if(this.props.data === newProps.data){
      return false;
    }
    return true;
  }
  • render함수 이전에 shouldComponentUpdate가 실행된다.
  • return값이 True면 render함수가 실행되고, False면 render가 실행되지 않는다.
  • concat을 쓰지 않고 push를 사용했다면 원본값이 바뀌어서 성능을 향상하기 어렵다.
var a = [1,2];
var b = Array.from(a);
b.push(3);
  • array에서 Array.from을 쓰면 복제가 된다.
var a = {name:'egoing'};
var b = Object.assign({},a);
  • 객체에서는 Object.assign을 사용하면 복제가 된다.
  • immutable
  1. Update
constructor(props){
  super(props);
  this.state = {
    title:this.props.data.title
  }
}
  • 함수내에서 props를 불러오면 readonly롤 수정이 안된다. 이를 리액트에서 변수에 props를 지정하면 경고가 뜨게 해놓았다.
  • 그러므로 state화 함.
type="text" 
name="title" 
placeholder='title'
value={this.state.title}
onChange={function(e){
  this.setState({title:e.target.value});
}.bind(this)}
  • onChange를 사용하여 readonly를 해제한다.
  • 해당값은 value로 지정한다.
inputFOrmHandler(e){
  this.setState({[e.target.name]:e.target.value});
}
onChange={this.inputFormHandler.bind(this)}
  • inputFormHandler 함수로 반복되는 부분 제거
  • e.target.name을 써서 title과 desc를 대응하도록 한다.
this.inputFormHandler = this.inputFormHandler.bind(this);
  • constructor안에 상기문을 입력하면 bind(this)를 매번 입력하지 않아도 된다.
  1. Delete
if(_mode === 'delete'){
  if(window.confirm('really?')){
    var _contents = Array.from(this.state.contents);
    var i = 0;
    while(i < this.state.contents.length){
      if(_contents[i].id === this.state.selected_content_id){
        _contents.splice(i,1);
        break;
      }
      i = i +1;
    }
    this.setState({
      mode:'welcome',
      contents:_contents
    })
  }
}
  • confirm창은 window.confirm사용
  • delete는 splice(시작, 갯수)지정으로 삭제한다.
  1. ps
  • immutable.js
  • react router : react는 하나의 url로 모든 페이지를 만듦. url에따라서 적당한 component가 실행되게 만든다.
  • npm run eject : create-react-app의 여러 설정을 수정 가능
  • redux : 중앙에 저장소가 있고 component가 연결된다.
  • react native : react와 같은 방법으로 native 앱을 만들수 있다.
  1. …this.state
  • 앞의 내용을 그대로 유지한다는 의미
  1. {this.state.movies ? this._renderMovies() : ‘Loading’}
  • this.state.movies가 참이면 this._renderMovies()가 실행되고, 거짓이면 ‘Loading’이 출력된다.
  1. component 중에 state 및 생애주기함수가 필요없는 것은 function으로 간단하게 표현한다.
  2. class에서는 props에 this가 필요하지만 function에는 this가 필요없다. 이미 props를 쓰니까
  3. fetch(‘주소’)를 이용해서 불러올수 있다.
  4. 새로고침 없이 작업이 가능하고, 리액트와 작업이 간편하기 떄문에 AJAX 추천
  fetch('https://yts.mx/api/v2/list_movies.json?sort_by=rating')
  .then(potato => potato.json())
  .then(jason => console.log(jason))
  .catch(err => console.log(err))
  1. fetch로 url을 불러오고 성공적으로 수행했을때 .then으로 받고 실패 했을때 catch로 받을 수 있다.

  2. fetch가 좋은 이유는 url을 AJAX로 심플하게 불러올수 있어서 좋다.

  3. .then이 많아지면 callback hell에 빠질 수 있다. 이때 사용하는 것이 sync, await

  • async는 비동기로 이전작업이 끝나지 않아도 다음 작업이 시작하는 형태
componentDidMount(){
  this._getMovies();
}
_getMovies = async () => {
  const movies = await this._callApi()
}
_callApi = () => {
  fetch('https://yts.mx/api/v2/list_movies.json?sort_by=rating')
  .then(potato => potato.json())
  .then(jason => console.log(jason))
  .catch(err => console.log(err))
}
  • did mount하고 나면, get movies를 한다. 이건 asynchronous function인데 movies라는 variable을 갖고 있다. 그리고 이건 value를 갖고 있는데 call api라는 function을 await 모드에서
  • await으로 하는것은 call api 기능이 끝나는 것(성공적으로 수행이 아니라)을 기다리고 있는것이다.
  • _callApi()의 return value를 movies에 set
  • => arrow function은 return이 필요없다.
  1. className은 css에서 class를 의미
  2. 배포
  • npm run build
  • gh-pages 깃허브 페이지에 배포시 설치
  • npm install –save gh-pages
"scripts": {
  "predeploy": "npm run build",
  "deploy": "gh-pages -d build"
}
"homepage": "https://username.github.io/movie_app"
  • package.json 에 상기 내용 추가
  1. npm install react-router-dom 라우터 설치
import { BrowserRouter, Route} from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";

function App() {
  return(
    <BrowserRouter>
      <Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
    </BrowserRouter>
  );
}

export default App;
  1. react route는 주소 경로에 맞는 것을 모두 보여준다.
  2. 그 경로에 딱 맞는 것만 출력하려면 exact={true} 삽입
import React from "react";
import { Link } from "react-router-dom";

function Navigation(){
    return(
        <div>
            <Link to="/" >Home</Link>
            <Link to="/about" >About</Link>
        </div>
    );
}

export default Navigation;
  1. Navigation 작성시 Router는 href가 아닌 Link to를 사용한다.

React class vs function style

  • 최신 react에 hook이 지원하면서 function에 state와 life cycle function을 사용할수 있게 되었다.
  • 내장 hook은 보통 use라고 적혀있다.
  • useState는 배열로 첫번째 값은 상태값, 두번째 값은 상태를 바꿀 수 있는 함수
  • useEffect = componentDIdMount & componentDidUpdated
  • useEffect의 return은 다시 시작될때 clean up 한다.
  • useEffect의 두번째 인자를 [xxx]로 넣으면 [xxx]안의 인자가 바뀌었을때만 실행된다.
  • 두번째 인자를 빈 배열[]로 넣으면 componentDidMount만 실행
2nd Deck

Book - 이상한 수학책 / 벤 올린

Book - 그림으로 배우는 네트워크 원리 / Gene