멀티캠퍼스 백엔드 과정 59일차[8월 29일] - 프로젝트를 위한 리액트 api + 팀프로젝트 피그마 이용

GoldenDusk·2023년 8월 29일
0
post-thumbnail

https://ko.legacy.reactjs.org/

1. State와 클래스형 컴포넌트

🍌 리액트 용어

state 정의하기

  • 우리가 클래스형 컴포넌트를 사용하는 이유 ? state를 사용하기 위함
  • state를 사용하려면 다음과 같이 state = { };라고 작성하여 state를 정의
import React from "react";

// 클래스형 컴포넌트가 되려면 App 클래스가 리액트가 제공하는 Component 클래스를 반드시 상속해야 한다.
class App extends React.Component {
  state = {
  };

state(상태) 특징

  1. 동적(사용자 동작) 데이터를 다룰 때 사용하는 개념(변경이 가능한)
  2. 객체(Object)
  3. props 컴포넌트 : 변수의 값을 저장기능
  4. 직접 접근 불가
  • 잘못된 접근 : state(private)는 직접접근이 안되기에 setState로 간접접근(getter, setter)
*this.state.count = -1;* 
  • 맞는 접근
minus = () => {
    this.setState({ count: -1 });
  };

상속(extend) 확장

  • 함수형 컴포넌트는 return JSX를 반환
  • 클래스형 컴포넌트는 render()함수가 JSX[js + html 문법]를 반환

render() 함수 사용하기

  • 클래스 형태의 App 컴포넌트를 작성.
  • 이제 App 컴포넌트가 JSX를
    반환.
  • 그런데 지금의 App 컴포넌트는 클래스라서(함수가 아니라서) return 문을 사용할 수 없고
 import React from "react";

// 클래스형 컴포넌트가 되려면 App 클래스가 리액트가 제공하는 Component 클래스를 반드시 상속해야 한다.
class App extends React.Component {
 render(){
		return <h1> I'm a class component </h1>;
	}
}

export default App;
  • 그래서 함수 형태의 App 컴포넌트처럼 JSX를 반환할 수가 없기 때문에 render( ) 함수를 사용
  • 함수형 컴포넌트는 return 문이 JSX를 반환하지만 클래스형 컴포넌트는 render( ) 함수는 JSX를 반환.
  • 리액트는 클래스형 컴포넌트의 render( ) 함수를 자동으로 실행시켜 준다.

isLodingState()

🍌 리액트에서 마운트(mount)로 분류하는 생명주기 함수

  • mount : 운영체제에서 사용할 있게 해주는 처리기
  • 실행 순서 및 종류
  1. constructor
  2. render
  3. componentDidMount()
  4. componentDidUpdate() : 업데이트 될 때
  5. componentWilUpdate()

관련 예제 코드

import React from "react";

// 클래스형 컴포넌트가 되려면 App 클래스가 리액트가 제공하는 Component 클래스를 반드시 상속해야 한다.
class App extends React.Component {
  state = {
    count: 0,
  };

  add = () => {
    this.setState((current) => ({ count: this.state.count + 1 })); //current는 인자값
  };

  minus = () => {
    this.setState((current) => ({ count: this.state.count + -1 }));
  };

  constructor(props) {
    //1. constructor가 먼저 실행되고
    super(props);
    console.log("hello constructor");
  }

  componentDidMount() {
    // 3. 그 다음에 componentDidMount
    console.log("I'm rendering!");
  }

  componentDidUpdate() {
    // 4. 그 다음에 componentDidUpdate
    console.log("I just updated");
  }
  
  componentWilUpdate() {
    // 5. 그 다음에 삭제 될 때
    console.log("Goodbye!");
  }

  render() {
    // 2. 그 다음에 render가 실행
    console.log("hello render!");
    return (
      <div>
        <h1>The number is {this.state.count}</h1>
        <button onClick={this.add}>Add</button>
        <button onClick={this.minus}>Minus</button>
      </div>
    );
  }
}

export default App;

🍌 state로 숫자 증감 기능 만들어 보기

  • App.js
import React from "react";

// 클래스형 컴포넌트가 되려면 App 클래스가 리액트가 제공하는 Component 클래스를 반드시 상속해야 한다.
class App extends React.Component {
  state = {
    count: 0,
  };

  add = () => {
    //this.state.count = 1;
    this.setState((current) => ({ count: this.state.count + 1 })); //current는 인자값
  };

  minus = () => {
    // console.log('minus')
    //1. this.state.count = -1; state(private)는 직접접근이 안되기에 setState로 간접접근(getter, setter)
    // 2. this.setState({ count: this.state.count - 1 }); //count state를 -1만큼 감소
    // 3. current인자를 받아 객체  { count: this.state.count - 1 }를 반환하는 함수로 작성
    this.setState((current) => ({ 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>
    );
  }
}

export default App;

🍌 리액트의 장점

  • 바뀌는 부분만 바뀌어지고, 새로고침이 이루어지지 않음
  • 사용자에게 좋음

2. 영화 평점 만들기

🍌 axios 설치

🍌 json viewer 확장프로그램 설치

🍌 movie list 로딩 만들기

import React from "react";

class App extends React.Component {
  state = {
    isLoading: true,
    movies: [], //영화데이터를 저장할 배열
  };

  componentDidMount() {
    //영화 앱을 데이터를 불러올 것이다.
    setTimeout(() => {
      this.setState({ isLoading: false });
    }, 6000); //6초후 We are Loding
  }

  render() {
    const { isLoading } = this.state; //구조 분해 할당 : this.state를 입력하지 않아도 된다.
    return <div>{isLoading ? "Loding.." : "영화 데이터를 출력"}</div>;
  }
}

export default App;

🍌 데이터 가져오기

  • 데이터를 잘 가져오는 것을 볼 수 있음

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

class App extends React.Component {
  state = {
    isLoading: true,
    movies: [], //영화데이터를 저장할 배열
  };

  getMovies = async () => {
    // 액세스 실행
    const movies = await axios.get("https://yts-proxy.now.sh/list_movies.json");
    console.log(movies);
  };

  componentDidMount() {
    //영화 앱을 데이터를 불러올 것이다.
    //setTimeout(() => {
    //  this.setState({ isLoading: false });
    //}, 6000); //6초후 We are Loding
    this.getMovies();
  }

  render() {
    const { isLoading } = this.state; //구조 분해 할당 : this.state를 입력하지 않아도 된다.
    return <div>{isLoading ? "Loading.." : "영화 데이터를 출력"}</div>;
  }
}

export default App;

🍌 구조화

  • 구조화 해주기
class App extends React.Component {
  state = {
    isLoading: true,
    movies: [], //영화데이터를 저장할 배열
  };

  getMovies = async () => {
    const {
      // 데이터가 있는데 그 안에는 movies라는 데이터가 있음
      data: {
        data: { movies },
      },
    } = await axios.get("https://yts-proxy.now.sh/list_movies.json");
    //console.log(movies);//movies.data.data.movies 정연산자 적용 => 구조 분해 할당하여 객체 구조화 ES6
    this.setState({ movies, isLoading: false });
  };

  componentDidMount() {
    //영화 앱을 데이터를 불러올 것이다.
    //setTimeout(() => {
    //  this.setState({ isLoading: false });
    //}, 6000); //6초후 We are Loding
    this.getMovies();
  }

  render() {
    const { isLoading } = this.state; //구조 분해 할당 : this.state를 입력하지 않아도 된다.
    return <div>{isLoading ? "Loading.." : "영화 데이터를 출력"}</div>;
  }
}

export default App;
  • api 응용해서 가져오는 방법
  • ?sort_by=rating 로 수정함
getMovies = async () => {
    const {
      // 데이터가 있는데 그 안에는 movies라는 데이터가 있음
      data: {
        data: { movies },
      },
    } = await axios.get("https://yts-proxy.now.sh/list_movies.json?sort_by=rating");  // json 다음에 ?로 api 가져오는 방법
    //console.log(movies);//movies.data.data.movies 정연산자 적용 => 구조 분해 할당하여 객체 구조화 ES6
    this.setState({ movies, isLoading: false });
  };

🍌 api를 이용한 총 예제 코드

  • app.js
import axios from "axios";
import React from "react";
import "./App.css";
import Movie from "./Movie";

class App extends React.Component {
  state = {
    isLoading: true,
    movies: [], //영화데이터를 저장할 배열
  };

  getMovies = async () => {
    const {
      // 데이터가 있는데 그 안에는 movies라는 데이터가 있음
      data: {
        data: { movies },
      },
    } = await axios.get(
      "https://yts-proxy.now.sh/list_movies.json?sort_by=rating"
    ); // json 다음에 ?로 api 가져오는 방법
    //console.log(movies);//movies.data.data.movies 정연산자 적용 => 구조 분해 할당하여 객체 구조화 ES6
    this.setState({ movies, isLoading: false });
  };

  componentDidMount() {
    //영화 앱을 데이터를 불러올 것이다.
    //setTimeout(() => {
    //  this.setState({ isLoading: false });
    //}, 6000); //6초후 We are Loding
    this.getMovies();
  }

  render() {
    // 보여지는 부분
    const { isLoading, movies } = this.state; //구조 분해 할당 : this.state를 입력하지 않아도 된다.
    // 하나씩 받아오는 map
    return (
      <section class="container">
        {isLoading ? (
          <div class="loader">
            <span class="loader__text">Loading...</span>
          </div>
        ) : (
          <div class="movies">
            {movies.map((movie) => {
              return (
                <Movie
                  key={movie.id}
                  id={movie.id}
                  year={movie.year}
                  title={movie.title}
                  summary={movie.summary}
                  poster={movie.medium_cover_image}
                />
              );
            })}
          </div>
        )}
      </section>
    );
  }
}
export default App;
  • Movie.js
import PropTypes from "prop-types";
import React from "react";
import "./Movie.css";

function Movie({ title, year, summary, poster }) {
  // 파라미터로 받아옴
  return (
    <div>
      <img src={poster} alt={title} title={title} />
      <div class="movie">
        <h3 class="movie_title">{title}</h3>
        <h5 class="movie_year">{year}</h5>
        <p class="movie_summary">{summary}</p>
      </div>
    </div>
  );
}

Movie.prototype = {
  // dto에서 정의한 것과 같은 효과
  year: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  poster: PropTypes.string.isRequired,
};

export default Movie;
  • index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));
  • Movie.css
.movies .movie {
  background-color: white;
  margin-bottom: 70px;
  font-weight: 300;
  padding: 20px;
  border-radius: 5px;
  color: #adaeb9;
  box-shadow: 0 13px 27px -5px rgba(50, 50, 93, 0.25),
    0 8px 16px -8px rgba(0, 0, 0, 0.3), 0 -6px 16px -6px rgba(0, 0, 0, 0.025);
}

.movies .movie a {
  display: grid;
  grid-template-columns: minmax(150px, 1fr) 2fr;
  grid-gap: 20px;
  text-decoration: none;
  color: inherit;
}

.movie img {
  position: relative;
  top: -50px;
  max-width: 150px;
  width: 100%;
  margin-right: 30px;
  box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25),
    0 18px 36px -18px rgba(0, 0, 0, 0.3), 0 -12px 36px -8px rgba(0, 0, 0, 0.025);
}

.movie .movie__title,
.movie .movie__year {
  margin: 0;
  font-weight: 300;
}

.movie .movie__title {
  margin-bottom: 5px;
  font-size: 24px;
  color: #2c2c2c;
}

.movie .movie__genres {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  margin: 5px 0px;
}

.movie__genres li,
.movie .movie__year {
  margin-right: 10px;
  font-size: 14px;
}

팀 프로젝트를 위한 메인 화면 피그마 이용하기 + 화면 기능 분석 => 아직 비공개

🧳 블로그 링크 바로가기

회고

오늘은 리액트 api 이용해봤다. 근데 깃허브 공부 좀 하루 날 잡고 해야겠다 기본적인 기능이나 이런것은 아는데 안에 내부 동작 구조나 이런 부분을 공부해야 겠다는 생각이 들었다

또한 오늘 2시간은 팀플 기능적인 부분과 메인화면 구성했다. 메인화면 구성은 각자 해보고 발표해보는 식으로 했는데 나는 피그마랑 피그마의 피그잼이 현업에서 많이 쓰인다고 해서 피그마를 이용해서 화면 구성을 해봤다. 벨로그에도 관련 글 있던데 그거 참고해서 보완도 해야겠다. 나머지 팀원들은 기능 분석을 했다.

profile
내 지식을 기록하여, 다른 사람들과 공유하여 함께 발전하는 사람이 되고 싶다. gitbook에도 정리중 ~

0개의 댓글