React-Inflearn Study

TigerStoneV·2022년 4월 11일
0
post-thumbnail
post-custom-banner

4/3 인프런 리액트 강의 공부

  • React는 프론트엔드 라이브러리다.
  • user interface를 동적으로 만들어주기 위해선 노력해야한다.
  • Js의 DOM과 상태관리는 어느정도의 한계가 있다.
  • 그래서 라이브러리나 프레임워크를 쓴다. (생산성, 유지보수)

삼대장 (React, Angular, Vue)

  • Angular
    - 1. 다양한 기능 내장됨.
      1. 타입스크립트 사용의 거의 필수
  • React
    - 1. 라이브러리!
      1. 페이스북 측에서 개발되었고 , View에 중점
      1. 생태계가 넓고 뜨겁다. 공식 라이브러리 같은건 없는거 같다
  • Vue
    - 1. 개발자가 사용하기 쉽다.
      1. 공식 라우터와 공식 상태관리 라이브러리가 있다.
      1. JSX도 사용이 가능하다.
      1. 리액트와 앵귤러의 장점을 합쳐놓은 느낌이다.
  • 결론
    - 어쨋든 한번씩 맛보면 좋다.
    • 어느 하나를 꼽는 것보다 개발자에게 맞는 라이브러리나 프레임워크를 쓰는것이 좋다.

React Virtual Dom

  • MVC,MVVM,MVW 등을 사용하던 기존 웹 프레임워크/ 라이브러리
  • 공통점: Model, 양반향 바인딩!
  • 변화(Mutation) 특정 이벤트
  • 리액트가 나온 이유는 Mutation을 하지말자! 그대신 데이터가 바뀌면 그냥 View를 날려버리고 새로 만들어버리면 어떨까? 에서 개발되었다.
  • (개인적인 느낌): 성능 저하 대박일꺼같은데.. 리액트 괜히 선택했나?
  • 라고 하자마자 Virtual Dom (가상 DOM) 등장.
  • 데이터가 바뀌었을때 바뀐 데이터를 비교해 그 부분만 업데이트.

  • React에서만 Virtual Dom을 쓰나?
    - 아니다.
    • 다른 좋은 라이브러리, 프레임워크에서도 쓰인다.
    • 그럼에도 리액트인 이유는?
      • 어마어마한 생태계! (정글)
      • 사용하는 곳이 많다.
      • 한번 사용하면 만족한다.
      • hot해 hot해

Webpack

  • 프로젝트를 만들때 패키지를 관리 해준다.
  • build, bundling 준비 작업을 해준다.

Babel

  • babel is a javascript compiler

코드시작!

import React, { Component } from 'react';

class App extends Component {
  render() {
    return (
      <div>
        <h1>안녕하세요 리액트</h1>
      </div>
    );
  }
}

export default App;
  • import를 통해서 react를 불러오면서 시작해야한다.
  • render을 통해서 불러오는 것은 jsx를 써야한다.

JSX

  • html 같지만 지켜야할 몇가지 규칙이 있다.
  • js로 변환이 된다.
  • 태그는 꼭 닫혀있어야한다.
<div>
	<input> // Error
	<input /> // okay
</div> 
  • 두개이상 엘리먼트는 꼭 하나의 엘리먼트로 포함되어 있어야한다.
<div> hi </div>
<div> bye </div> //Error

<div>
	<div> hi </div>
    <div> bye </div> //Okay
</div>
  • fragment
<fragment>
	<div> hi </div>
    <div> bye </div> //Okay
</fragment>
// 불필요한 div를 지우고 할수 있다.
  • jsx안에 자바스크립트 값 사용하기.
//var
render(){
    	function foo(){
        	var a = 'hello ';
            if(true){
            	var a = 'bye';
                console.log(a) ; //bye
            }
            console.log(a) ;  //bye
        }
    }
//let
render(){
    	function foo(){
        	let a = 'hello ';
            if(true){
            	let a = 'bye';
                console.log(a) ; //bye
            }
            console.log(a) ;  //hello
        }
    }
  • 조건부 렌더링
class App extends Component {
  render() {
    return (
      <div>
        {
          1 + 1 === 2
          ? '맞다'
          : '틀리다'
        }
      </div>      
    );
  }
}
  render() {
    const name ="tiger" 
    return (      
      <flagment>
      <div>        
        {
          name === 'tiger' && <div> 타이거 </div>
        }
      </div>
      </flagment>            
    );
  }
  • jsx 내부 css
render(){
  const style = {
        backgroudColor: 'black', 
        // background-color > backgroundColor 카멜케이스 적용
        padding: '16px',
        color:'red'
      }
	return(
    	<div style = {style}> hi
        </div>
    )
}
  • in class
import React, { Component } from 'react';
import './aqua.css';
  class App extends Component {
	render(){
      return (
      	 <div className="aqua">
         // js에선 <div class="aqua">
         hi
         </div>
      )
    }
   }
  • 주석
    - //도 렌더링이 되고
    • /* */ 도 렌더링이 된다.
<div>
	{/*이렇게 써야함*/}
    <h1 
    	something=blahblah // 여기선 이 주석을 사용
     >
     hi
     </h1>
</div>

Props 와 State

  • react에서 데이터를 다룰때 사용하는 것이다.
  • 🌕 props: 부모컴퍼넌트가 자식컴퍼넌트한테 값을 전달할때 사용한다. (별 다섯개)
// MyName.js
import React, {Component} from 'react';
class MyName extends Component {
	render(){
    	return(
        	<div>
            안녕하세요 ! 제이름은 <b>Tiger</b>입니당.
            안녕하세요 ! 제이름은 <b>{this.props.name}</b>입니당.
            </div>
        )
    }
}
export default MyName;
// App.js
import React, { Component } from "react";
import MyName from "./MyName";
class App extends Component {
  render() {
    return <MyName name="리액트" />;
  }
}
export default App;
  • 기본값 사용
import React, { Component } from "react";
class MyName extends Component {
  static defaultProps = {
  	name: '기본이름'
  } // 방식 1번째
  render() {
    return (
      <div>
        안녕하세요 ! 제이름은 <b>Tiger</b>입니당. <br />
        안녕하세요 ! 제이름은 {this.props.name} 입니당.
      </div>
    );
  }
}
MyName.defaultProps = {
	name: '기본이름 2 '
} // 방식 2번째
export default MyName;
  • 함수형 컴퍼넌트
import React from "react";

const MyName = ({ name }) => {
  // 비구조화 할당
  return <div>안녕하세요 함수형 컴퍼넌트 {name} 입니다.</div>;
};
MyName.defaultProps = {
  name: "함수형 기본이름"
};

export default MyName;

// 두개의 주요 차이점은 state와 lifecycle의 유무이다.
// 어떨때 사용해야 하는가 초기 마운트 속도가 더 빠르다.
// 불필요한 기능이 없어서 메모리자원을 덜 잡아먹는다.
  • 🌕 State : state는 내부에서 변경할 수 있고 변경 할 때는 언제나 setState 라는 함수를 사용한다.
// Counter.js
import React, { Component } from "react";

class Counter extends Component {
  state = {
    number: 0
  };
  handleIncrease = () => {
    this.setState({
      number: this.state.number + 1
    });
  };
  handleDecrease = () => {
    this.setState({
      number: this.state.number - 1
    });
  };

  render() {
    return (
      <div>
        <h1> counter </h1>
        <div> 값: {this.state.number} </div>
        <button onClick={this.handleIncrease}>+</button>
        <button onClick={this.handleDecrease}>-</button>
      </div>
    );
  }
}
export default Counter;
//App.js

import React, { Component } from "react";

import Counter from "./Counter";
class App extends Component {
  render() {
    return <Counter />;
  }
}
export default App;
  • state가 바뀔때 마다 Rerendering이 된다.
  • props와 state의 차이
    -1. props는 읽기전용, state는 변경도 가능하다는 것
    -2. props는 부모에서 자식으로 데이터를 넘겨주는것이고 state는 자기자신!

LifeCycle API

  • 생명주기
  • 컴퍼넌트가 나타날때 업데이트 될때 사라질 때 중간중간 과정에서 작업을 하고싶을때 사용한다.
  • API 종류가 굉장히 많은 편이다.
    1. Mounting: component가 등록될때
    • constructor = 생성자 함수
    • getDrivedStateFromProps = props로 받은 값을 state로 동기화를 시키고 싶을때 쓰는 함수
    • componentDidMount = 우리가 만든 컴퍼넌트가 브라우저에 나타난 시점에 어떠한 작업을 하겠다라는 것을 명시한다
    1. Updating: component가 변경될때
      - getDrivedStateFromProps
    • shouldComponentUpdate = 컴퍼넌트가 업데이트되는 성능을 최적하고시키고 싶을때 사용. Boolean Data가 반환되는데 true면 렌더링이되고 false면 stop이다.
    • getSnapshotBeforeUpdate = 렌더링을 하고나서 업데이트를 하기전에 스크롤의 위치 해당 돔의 크기를 사전에 가져오고싶다 라는 작업을 할때 사용한다.
    • componentDidUpdate = 업데이트가 끝나고 하는 작업이다
    1. UnMounting: component가 삭제될때
      - componentWillUnmount = 스크롤이벤트 같은것 삭제.

컴퍼넌트 초기 생성

  • constructor

constructor(props) {
  super(props);
}
  • 컴포넌트 생성자 함수이다. 컴포넌트가 새로 만들어질 때마다 함 이 함수가 호출된다.
  • componentWillMount

componentDidMount() {
  // 외부 라이브러리 연동: D3, masonry, etc
  // 컴포넌트에서 필요한 데이터 요청: Ajax, GraphQL, etc
  // DOM 에 관련된 작업: 스크롤 설정, 크기 읽어오기 등
}
  • 이 API 는 컴포넌트가 여러분의 화면에 나가나기 직전에 호출되는 API 인데요, 이 API 에 대해선 별로 신경쓰지 않아도 된다.
  • 원래는 주로 브라우저가 아닌 환경에서 (서버사이드)도 호출하는 용도로 사용했었는데, 이 API 가 더 이상 필요하지 않게 되어 리액트 v16.3 에서는 해당 API 가 deprecated 되었으니, 아, 옛날엔 이러한 API가 사용됐었구나.. 하고 알아만 두면된다.
  • v16.3 이후부터는 UNSAFE_componentWillMount() 라는 이름으로 사용된다.
  • 기존에 이 API 에서 하던 것들은 위에 있는 constructor 와 아래에서 다뤄볼 componentDidMount 에서 충분히 처리 할 수 있다.
  • componentDidMount

componentDidMount() {
  // 외부 라이브러리 연동: D3, masonry, etc
  // 컴포넌트에서 필요한 데이터 요청: Ajax, GraphQL, etc
  // DOM 에 관련된 작업: 스크롤 설정, 크기 읽어오기 등
}
  • 이 API는 사용자의 컴포넌트가 화면에 나타났을때 호출이된다.
  • 주로 D3, masonry처럼 DOM을 사용해야하는 외부 라이브러리를 연동 하거나 해당 컴포넌트에서 필요로 하는 데이터를 요청하기위해 axios,fetch등을 통하여 요청을 하거나 DOM의 속성을 읽거나 직접 변경하는 작업을 진행한다.

컴퍼넌트 업데이트

  • static getDerivedStateFromProps()

static getDerivedStateFromProps(nextProps, prevState) {
  // 여기서는 setState 를 하는 것이 아니라
  // 특정 props 가 바뀔 때 설정하고 설정하고 싶은 state 값을 리턴하는 형태로
  // 사용됩니다.
  /*
  if (nextProps.value !== prevState.value) {
    return { value: nextProps.value };
  }
  return null; // null 을 리턴하면 따로 업데이트 할 것은 없다라는 의미
  */
}
  • shouldComponentUpdate

shouldComponentUpdate(nextProps, nextState) {
  // return false 하면 업데이트를 안함
  // return this.props.checked !== nextProps.checked
  return true;
}
  • 특정조건에 따라 렌더링을 막아줄 수 있는 api

  • componentWillUpdate

  • 더이상 사용되지 않는다.

  • getSnapshotBeforeUpdate()

    	1. render()
    	2. getSnapshotBeforeUpdate()
    	3. 실제 DOM 에 변화 발생
    	4. componentDidUpdate    
    getSnapshotBeforeUpdate(prevProps, prevState) {
    // DOM 업데이트가 일어나기 직전의 시점입니다.
    // 새 데이터가 상단에 추가되어도 스크롤바를 유지해보겠습니다.
    // scrollHeight 는 전 후를 비교해서 스크롤 위치를 설정하기 위함이고,
    // scrollTop 은, 이 기능이 크롬에 이미 구현이 되어있는데, 
    // 이미 구현이 되어있다면 처리하지 않도록 하기 위함입니다.
    if (prevState.array !== this.state.array) {
      const {
        scrollTop, scrollHeight
      } = this.list;
    
      // 여기서 반환 하는 값은 componentDidMount 에서 snapshot 값으로 받아올 수 있습니다.
      return {
        scrollTop, scrollHeight
      };
    }
    }
    
    componentDidUpdate(prevProps, prevState, snapshot) {
    if (snapshot) {
      const { scrollTop } = this.list;
      if (scrollTop !== snapshot.scrollTop) return; // 기능이 이미 구현되어있다면 처리하지 않습니다.
      const diff = this.list.scrollHeight - snapshot.scrollHeight;
      this.list.scrollTop += diff;
    }
    }
  • componentDidUpdate

컴포넌트 제거

  • componentWillUnmount

componentWillUnmount() {
  // 이벤트, setTimeout, 외부 라이브러리 인스턴스 제거
}
  • 컴포넌트가 사라지게될때 호출됨.

컴포넌트에 에러 발생

  • componentDidCatch

componentDidCatch(error, info) {
  this.setState({
    error: true
  });
}
  • 에러발생시 실행.

리액트 첫 시작.

  • Creat-react-app
    - React를 배우기에 가장 간편한 환경이고 새로운 싱글페이지 어플리케이션이다.
    • npm 혹은 yarn으로 실행을 하며 필자는 npm을 사용하여 노드버전 14.0 상위, npm 버전 5.6상위를 써서 작업했다.
//iterm
npx create-react-app my-app
//vscode
// my-app 열기
npm start

배열을 렌더링 할때

  • Key 가 없다면 비효율적인 렌더링이 진행된다.
  • 예를들어 번호만 있는곳에서 누군가를 찾을때 일일히 한명씩 검사를 받으면서 번호가 누구인지 물어봐야하지만,
  • 이름과 번호가 같이 나와있다면 내가 원하는 이름을 불러 한번에 찾을수 있는 그런 느낌이다.

배열 데이터 제거

  • 불변성을 유지하면서 제거하려면
  • .slice 혹은 .fiter를 써야한다.
  • .slice
const numbers = [1,2,3,4,5]
console.log(numbers.slice(0,2))
// 0부터~2까지 index 까지의 배열을 가져와 새로운 배열출력

-.fliter

const numbers = [1,2,3,4,5];
console.log(numbers.filter(n => n>3)) // 3보다 큰
console.log(numbers.filter(n => n!== 3)) // 3이아닌

데이터 수정

  • .slice 혹은 .map
const numbers = [1,2,3,4,5]
[
	...numbers.slice(0,2),
    0
    ...numbers.slice(3,5)
]
numbers.map(n => {
	if (n === 3 {
    return 9
    })
  })

불변성 유지 이유

  • shouldComponentUpdate을 쓰지않는다면 우선 복잡해진다.
  • 객체와 배열값을 변경 혹은 제거할때는 불변성을 유지해야한다.

DOM에 직접 접근

  • ref
    1. 함수사용
    1. React.createRef()

추후 공부해야 할만한것

  • redux :쉽고 사용하기 위한 발악
  • mobx
  • 리액트 라우더
  • 타입스크립트
  • Jest,Enzyme

열심히 하자


유용한 사이트

profile
개발 삽질하는 돌호랑이
post-custom-banner

0개의 댓글