Earn this, Earn it.

React - 기초 공부 본문

[개발 공부]

React - 기초 공부

Narastro 2021. 9. 21. 11:49

2021년 7월 16일 from velog

[Nomacoder] React.js로 영화 웹서비스 만들기 강의를 복습한 내용입니다.

JSX

React의 특유한 로직으로, 렌더링과 UI가 연결된 특징을 갖는다. 마치 HTML+Javascript. 자세한 것은 밑에서 다루도록 하고 쉽게 말해 둘 다 포함하는 Component를 다룬다고 볼 수 있다.

Component란?

Javascript 함수와 유사하며, props(속성을 나타내는 데이터)라는 임의의 입력을 받은 후 React Element를 반환한다. 크게 function과 class 두 가지 유형이 있다.
아래는 코드 예시이다.

//함수형
function App(props){
    return <h1>Hello, {props.name}</h1>
}
//클래스형
class Detail extends React.Component{
    render(){
        return <h1>Hello, {this.props.name}</h1>
    }
}

Props?

Component에 정보를 전달하는 데이터(속성을 나타내는 데이터). 아래 예제로 보자.

<Food fav="spicy" />
...
function Food(props){
    console.log(props)
                    // { fav:"spicy" }
}

웹사이트에 동적 데이터 렌더링

{ } 안에 쓰면 javascript 코드처럼 사용할 수 있다. 따라서 map함수를 이용해서 movies를 렌더링해보자.

<div className="movies">
        {movies.map((movie) => (
           <Movie
                key={movie.id}        //각 객체는 유일해야하므로 key를 추가해줘야한다.
                id={movie.id}
                year={movie.year}
                title={movie.title}
                summary={movie.summary}
                poster={movie.medium_cover_image}
                genres={movie.genres}
           />
        ))}
</div>

props 타입 지정

npm i prop-types

대소문자 구별 주의!

import PropTypes from "prop-types";

Movie.propTypes = {
  id: PropTypes.number.isRequired,
  year: PropTypes.number.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};

각 component에서 렌더링시 미리 타입을 지정해주면 에러 방지에 좋겠다
자세한 건 공식문서 참고하자

State

동적 데이터를 다룰 때 사용하는 자바스크립트 객체로,
Component를 class형으로 정의하였을 때 제공되는 기능.
Class 내에서 수정시 this.setState({})를 통해 수정할 수 있다. (업데이트 발생)
또한 초기값을 선언할 필요는 없다.

* 꿀팁

this.setState(current=>({count:current.count+1}))

처럼 Arrow 함수를 이용해 현재 상태를 가져올 수 있다.

* 꼭 기억할 것

"매순간 setState 호출시마다 React는 새로운 State와 함께 render 함수를 호출한다."

Component 생명주기

아래 그림을 보고 필요에 따라 다음 함수들을 잘 이용하면 되겠다.

생명주기


(출처:https://ko.reactjs.org/docs/react-component.html)

1. 마운트

Component의 인스턴스 생성되어 DOM 상에 삽입될 때 순서대로 호출되는 메서드.

  • constructor() : 클래스를 만들 때 호출
  • render()
  • componentDidMount() : Component가 웹사이트로 갈 때
    (잘 안 쓰임)
    static getDerivedStateFromProps()

2. 업데이트

props 또는 state가 변경되면 갱신이 발생하는 메서드.

  • render()
  • componentDidUpdate()
    (잘 안 쓰임)
    getSnapshotBeforeUpdate()
    static getDerivedStateFromProps()
    shouldComponentUpdate()

3. 언마운트

컴포넌트가 DOM 상에서 제거될 때에 호출되는 메서드.

  • componentWillUnmount()

데이터 fetch (Axios를 이용)

npm i axios

비동기적으로 fetch하기

import axios from "axios";

class Home ...
    getMovies = async () =>{
    ...
            const movies = await axios.get(URL);
    ...
    }

여기서, componentDidMount() 에 위의 함수를 호출해준다.

        ...
        componentDidMount() {
            this.getMovies();
      }
    ...

로딩화면

1. state에 isLoading 추가

state = {
    isLoading: true,
    ...
  };

2. fetch가 끝나면 isLoading을 false로 처리

getMovies = async () => {
    ...
    await axios.get(
      "https://yts-proxy.now.sh/list_movies.json?sort_by=rating"
    );
    this.setState({ ..., isLoading: false });
  };

3. render()에 isLoading에 따라 나눠서 렌더링(삼항연산자 사용)

 render() {
    const { isLoading, movies } = this.state;
    return (
      <section className="container">
        { isLoading ? (
          <div className="loader">
            <span className="loader__text">Loading...</span>
          </div>
        ) : ...

className, htmlFor를 활용하자!

React 특성상 HTML과 Javascript를 같이 사용하므로 class 대신 className, for 대신 htmlFor를 활용하자!

CSS 새로 배운점

flex-wrap : wrap

요소들이 가능한 영역 내에서 여러행으로 나누어 표현됨.
nowrap시 요소들이 강제로 한 줄에 배치됨.

box-shadow: ...

직접 설정하는 것보다 다른 사이트 가서 요소 추출해오는 방법이...!

깃허브 페이지 만들기

npm i gh-pages

package.json에 다음을 추가

"homepage":"https://[USER_NAME].github.io/[PROJECT_NAME]"
"scripts":...,
    "deploy":"gh-pages -d build",
        "predeploy":"npm run build"

npm run deploy 입력시 predeploy가 먼저 실행되면서 build되고 gh-page가 생성됨.

React-router-dom

네이게이션을 만들어주는 패키지

npm i react-router-dom

App.js

App.js에서 라우터를 만든다.

import { HashRouter, Route } from "react-router-dom";

function App() {
  return (
    <HashRouter>
      <Navigation />
      <Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
      <Route path="/movie/:id" component={Detail} />
    </HashRouter>
  );
}
  • BrowserRouter도 있지만 HashRouter를 쓰는 이유, 깃허브 페이지에 정확히 설정하기 어렵다?
  • Route 안에 path(경로)와 component(렌더링할 스크린) props 2가지
  • exact={true} 설정시 URL 중복을 막을 수 있다. (ex. /movie가 요청되는 경우 /와 /movie가 모두 렌더링 되는 문제가 생김)

Navigation.js

import { Link } from "react-router-dom";

function Navigation() {
  return (
    <div className="nav">
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </div>
  );
}
  • 페이지가 새로고침 되고 리액트가 죽는 것을 방지하기 위해 a href ... 대신 Link to=...를 사용한다.
  • Link를 쓰고 싶다면 라우터 안에서 사용해야 함!

Link를 통해 데이터를 보내려면?

<Link to = { pathname:"/about",
        state: {
                fromNavigation:true...
                }
             }>
  • URL을 이용해 데이터를 보내는 방법도 있으나, 이 방법을 더 애용하자.

잘못된 경로로 접근시 홈으로 이동시키기

React의 기본 props인 history를 이용해
history.push("/");

class Detail extends React.Component {
  componentDidMount() {
    const { location, history } = this.props;
    if (location.state === undefined) {
      history.push("/");
    }

끝으로...

React hook을 배워야겠다.
그리고 다양한 API를 이용하여 새로운 앱을 시도해보고 싶다..
왜 다들 프레임워크를 해본 사람을 찾는지 알 것 같다. 숙련되면 좋을 것 같다.
더 노력하자. 아자아자!

'[개발 공부]' 카테고리의 다른 글

TIL - Process Management  (0) 2021.09.21
TIL - Cache & Crawling  (0) 2021.09.21
TIL - Linux  (0) 2021.09.21
TIL - Git과 JavaScript의 Array와 Set  (0) 2021.09.21
JavaScript - 기초 복습  (0) 2021.09.21