본문 바로가기
끄적끄적/리액트 공부 - 노마드 코더

[노마드 코더] 영화 웹 서비스 만들기 - 실전형 리액트 Hooks 적용 - useTitle

by 레일라오리덕 2021. 5. 3.
728x90

오늘은 노마드 코더의 ReactJS로 영화 웹 서비스 만들기 예제에 실전형 리액트 Hooks 10가지 중 한가지인 useTitle을 적용해보았다.

 

import React, { useEffect } from "react";
import axios from "axios";
import Movie from "../components/Movie";
import "./Home.css";

class Home extends React.Component {
    state = {
        isLoading: true,
        movies: [],
        title: "Loading"
    };
    getTitle = () => {
        const htmlTitle = document.querySelector("title");
        htmlTitle.innerText = this.state.title;
    }
    getMovies = async () => {
        const {
            data: {
                data: { movies }
            }
        } = await axios.get("https://yts-proxy.nomadcoders1.now.sh/list_movies.json?sort_by=rating");
        this.setState({ movies, isLoading: false, title: "Home" }, this.getTitle);
    };
    componentDidMount() {
        console.log("didmount");
        this.getTitle();
        this.getMovies();
    }
    render() {
        const { isLoading, movies } = this.state;
        return (
            <section className="container">
                {isLoading ? (
                    <div className="loader">
                        <span className="loader__text">Loading...</span>
                    </div>
                ) : (
                    <div className="movies">
                        {movies.map(movie => (
                            <Movie
                                key={movie.id}
                                id={movie.id}
                                year={movie.year}
                                title={movie.title}
                                summary={movie.summary}
                                poster={movie.medium_cover_image}
                                genres={movie.genres}
                            />

                        ))}
                    </div>
                )}
            </section>
        );
    }
}

export default Home;
728x90

ReactJS로 영화 웹서비스 만들기 예제의 Home.js파일이다.

useTitle 훅스를 적용하여 데이터를 가져오는 동안 본문화면에 Loading...이라고 보여질 때 상단의 title또한 Loading으로 보여지고 데이터가 제대로 화면에 보여지면 title또한 Home으로 바뀌게 적용해보았다.

 

setState는 비동기식으로 this.setState에서 title: "Home"으로 지정을 해주어도 mount가 되고 난 후 한번만 title이 셋업되므로 setState후에 callback함수를 붙여주어, setState가 일어난 후에 무조건 this.getTitle이 실행되도록 해주었다.

 

두번째 코드에 써져있는 방식은 동일하고 this.getTitle을 함수형으로 호출해주었다.

import React, { useEffect } from "react";
import axios from "axios";
import Movie from "../components/Movie";
import "./Home.css";

class Home extends React.Component {
    state = {
        isLoading: true,
        movies: [],
        title: "Loading"
    };
    getTitle = () => {
        const htmlTitle = document.querySelector("title");
        htmlTitle.innerText = this.state.title;
    }
    getMovies = async () => {
        const {
            data: {
                data: { movies }
            }
        } = await axios.get("https://yts-proxy.nomadcoders1.now.sh/list_movies.json?sort_by=rating");
        this.setState({ movies, isLoading: false, title: "Home" }, () => {
            this.getTitle();
        });
    };
    componentDidMount() {
        console.log("didmount");
        this.getTitle();
        this.getMovies();
    }
    render() {
        const { isLoading, movies } = this.state;
        return (
            <section className="container">
                {isLoading ? (
                    <div className="loader">
                        <span className="loader__text">Loading...</span>
                    </div>
                ) : (
                    <div className="movies">
                        {movies.map(movie => (
                            <Movie
                                key={movie.id}
                                id={movie.id}
                                year={movie.year}
                                title={movie.title}
                                summary={movie.summary}
                                poster={movie.medium_cover_image}
                                genres={movie.genres}
                            />

                        ))}
                    </div>
                )}
            </section>
        );
    }
}

export default Home;
728x90

댓글