리액트 기초

sham·2021년 7월 29일
0

개요

왜 리액트를 쓰는가?

사용자 경험이 좋다.

  • 앱과 같은 자연스러운 자연스러운 인터페이스

데이터랑 화면의 일치가 쉽다.

  • 데이터 처리가 용이하다.

중복을 피할 수 있다.

  • 동일한 컴포넌트(조각)을 일제히 수정 가능하다.

리액트는 자바스크립트를 사용한다.

#0

실행하는 법

  • npx create-react-app [디렉토리 이름]

#1

리액트 사용하기

html 파일에 작성하지 않는 내용도 react는 자바스크립트로 만든 모든 요소를 생성해 html에 집어넣는다.

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

소스코드에는 빈 index.html파일만 보인다.

react는 소스코드에 처음부터 html를 넣지 않는다. 빈 html을 불러와서 컴포넌트에 작성한 것들을 추가하거나 제거한다.

virtual DOM, 존재하지 않는 소스코드를 react가 만들어 낸다.

#2

컴포넌트

//컴포넌트
ReactDOM.render(<App />, document.getElementById('root'));
  • 컴포넌트는 HTML를 반환하는 함수이다.
  • 리액트는 컴포넌트와 함께 동작한다.
  • 컴포넌트가 데이터를 보여준다.
  • 자바스크립트와 HTML 사이의 조합을 jsx라고 한다.
    • react에 특화된 유일한 개념.
//potato.js
import React from 'react';

function Potato(){
    return <h3>I love poooo</h3>;
}

export default Potato;
  • 리액트를 사용하기 위해서는 반드시 선언해야 한다.
    • import React from 'react';
    • 사용하지 않으면 jsx가 있는 component를 사용하는 것을 이해하지 못한다.
  • 컴포넌트를 선언할 때는 반드시 대문자로 선언해준다.
  • 함수를 선언하고 원하는 HTML를 리턴한다.
  • 다른 파일에서 만든 컴포넌트를 다른 파일에서 사용하려면 export 명령어로 함수를 export해주고 사용하려는 파일에서 import를 해줘야 한다.
//app.js

import React from 'react';
import Potato from './potato';

function App() {
  return (
    <div className="App">
      <Potato />
     <h1>aaa</h1>hello!
    </div>
  );
}

export default App;
  • 하나의 리액트 앱이 하나의 컴포넌트 만을 렌더링 하기 때문에 동시에 여러 컴포넌트를 렌더링 할 수 없다.
  • 모든 것을 렌더링할 하나의 파일(app) 안에 넣어야 한다.
  • app파일에서 함수를 import해 HTML 안에 넣어준다.
  • 리액트는 컴포넌트를 가져와서 브라우저가 이해할 수 있는 일반적인 HTML로 만든다.

웹팩 : 쪼개진 자바스크립트 파일을 html이 사용할 수 있도록 합쳐준다.

prop

jsx에서는 컴포넌트에 정보를 보낼 수 있다.

  • 부모 컴포넌트 → 자식 컴포넌트
function Food(prop){
  return (
    <h1>i like {prop.fav}</h1>
  )
}

function App() {
  return (
    <div>
      <h1>Hello!</h1>
      <Food fav="kimchi"/>
    </div>
  );
}
  • Food component에 fav라는 property를 kimchi라는 value로 준 것.
  • 문자열, 배열, 불리안 등 무슨 값이든 prop으로 줄 수가 있다.
  • 부모 컴포넌트가 보낸 인자들은 자식 컴포넌트(함수)의 하나의 인자에 전달된다.
  • prop의 요소 하나만 특정해서 인자로 받을 수도 있다.
    • prop.fav == {fav}

map

  • 배열의 각 요소에 접근할 수 있는 함수이다.
const foodarray = [
  {name : "kimchi",
  describe : "spicy"},
  
  {name : "ramen",
  describe : "yummy"},
  {name : "chicken",
  describe : "hot"},
  {name : "kimbam",
  describe : "delicious"}
];

foodarray.map(current =>{
  alert(current.name + " " + current.describe);
})
/* foodarray.map(funtion(current)
{
  alert(current.name + " " + current.describe);
})*/
import logo from './logo.svg';
import './App.css';

function Food(prop){
  return (
    <h1>i like {prop.name} {prop.name} is {prop.describe}</h1>
  )
}

const foodarray = [
  {name : "kimchi",
  describe : "spicy"},
  
  {name : "ramen",
  describe : "yummy"},
  {name : "chicken",
  describe : "hot"},
  {name : "kimbam",
  describe : "delicious"}
];

function App() {
  return (
    <div>
      <h1>Hello!</h1>

      {foodarray.map(item => <Food name={item.name} describe={item.describe}/>)}
        
    </div>
  );
}

export default App;
  • map을 통해 배열의 요소인 오브젝트(구조체)의 각각 값에 접근할 수가 있다.

map recap

function Food(prop){
  return (
    <h1>i like {prop.name} {prop.name} is {prop.describe}</h1>
  )
}

const foodarray = [
  {name : "kimchi",
  describe : "spicy"},
  
  {name : "ramen",
  describe : "yummy"},
  {name : "chicken",
  describe : "hot"},
  {name : "kimbam",
  describe : "delicious"}
];

function renderFood(dish){
  return <Food name={dish.name} describe={dish.describe}/>
}

function App() {
  return (
    <div>
      <h1>Hello!</h1>
      {foodarray.map(renderFood)}
    </div>
  );
}
  • 화살표 함수 말고도 곧바로 함수로 넘겨버릴 수도 있다.

Each child in a list should have a unique "key" prop. ⇒ 모든 react의 컴포넌트는 유일해야 하는데, 리스트 안에 집어 놓으면 유일성을 잃어버리게 된다.

  • 에러를 방지하기 위해서 리스트 마다 고유한 id를 추가해주어야 한다.
  • key를 함수에서 사용하지는 않지만, 리액트 내부에서 사용하게 된다.

Protection

  • 부모 컴포넌트로부터 전달받은 prop이 원하는 prop인지 체크해야 한다.
  • prop-types을 통해 알맞은 prop인지 체크할 수 있다.

npm i prop-types

Food.propTypes = {
  name:PropTypes.string.isRequired,
  describe:PropTypes.string.isRequired,
  rating:PropTypes.number.isRequired
}
  • 컴포넌트의 prop.PropTypes.기대하는 자료형.isRequired
  • 예상한 것과 다를 경우 에러를 발생하지만 예상한 것이 들어오지 않을 때는 에러라고 판단한지 않는다.
  • PropTypes으로 써야만 react가 알아듣는다.

#3

State

  • 동적 데이터와 함께 작업할 때 만들어진다.
  • state가 변경되면, 컴포넌트는 리렌더링 된다.
  • 컴포넌트의 수많은 요소를 전부 구현할 수 없기에 extends로 리액트의 컴포넌트를 가져온다.
class App extends React.Component{

}
  • App 컴포넌트는 React 컴포넌트이다.
  • class react component는 함수가 아니기에 리턴을 가지고 있지 않는다.
  • 클래스 컴포넌트가 가지고 있는 render 메소드를 App 컴포넌트가 가지고 있다.
  • 클래스 컴포넌트는 리액트 컴포넌트로부터 확장되며 무언가를 렌더링하는 클래스다.
  • 리액트는 자동적으로 모든 클래스 컴포넌트의 render 메소드를 실행하고자 한다.

클래스 컴포넌트와 함수 컴포넌트의 차이

import React from 'react';

class App extends React.Component {
  state = {
    count : 0
  };
  render() {
    return <div>
      <h1>count : {this.state.count}</h1>
      </div>
  }
}

export default App;
  • 클래스 컴포넌트에 존재하는 state는 구조체다.
  • 접근하려면 this.state로 접근해야만 한다.
  • state에 담기는 데이터는 변할 수 있는 데이터이다.
import React from 'react';

class App extends React.Component {
  state = {
    count : 0
  };
  add = () =>{
      console.log("add");
  };
  minus = () => {
    console.log("minus");
  };
  render() {
    return <div>
      <h1>count : {this.state.count}</h1>
      <button onClick={this.add}>plus</button>
      <button onClick={this.minus}>Minus</button>
      </div>
  }
  
}

export default App;
  • state의 값을 변경하기 위해 자바스크립트를 사용한다.
  • 따로 등록할 필요 없이 react의 내장된 onClick을 사용할 수 있다.
  • 클래스이기 때문에 this를 사용한다.

함수 = () ⇒ {} == 함수(){}

state 값 변경

  • state의 값을 직접 변경할 수 없다.
  • add나 minus 함수에서 this.state.count += 1, -=1 등으로 직접 접근하면, 리액트는 함수를 렌더링하지 않는다.
import React from 'react';

class App extends React.Component {
  state = {
    count : 0
  };
  add = () =>{
this.setState({count : this.state.count + 1})
};
  minus = () => {
    this.setState({count : this.state.count - 1})
  };
  render() {
    return <div>
      <h1>count : {this.state.count}</h1>
      <button onClick={this.add}>plus</button>
      <button onClick={this.minus}>Minus</button>
      </div>
  }
  
}

export default App;
  • setState()는 컴포넌트의 state 객체에 대한 업데이트를 실행한다.
  • setState()를 호출한다면 리액트는 자동으로 state를 수정하고 render()를 실행하여 다시 렌더링한다.
    • 변화가 생긴 부분만 다시 렌더링한다.
  • state를 직접 사용하는 것은 썩 좋은 방법은 아니다.

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

  • setState()에서 화살표 함수를 사용하면 state를 인자로 받게 된다.

컴포넌트 생명 주기

  • 리액트 컴포넌트에서 사용하는 유일한 함수는 render().
  • (extends한) 리액트 클래스 컴포넌트는 생명 주기 메소드를 가진다.
  • 생명 주기 메소드는 기본적으로 리액트가 컴포넌트를 생성하고 없애는 방식이다.
  • 리액트에서 컴포넌트가 생성될 때, render 전에, render 후에 호출되는 함수들이 있다.
import React from 'react';

  class App extends React.Component {
    state = {
      count : 0,
      data : 0
    };
    add = () =>{
  this.setState(current => ({count : current.count + 1}))
  };
    minus = () => {
      this.setState(current => ({count : current.count - 1}))
    };
    constructor(props) {
      super(props);
      console.log("constructor");
    }
    componentDidMount()
    {
      console.log("first rendering");
    }
    componentDidUpdate()
    {
      console.log("just update");
    }
    componentWillUnmount()
    {
      console.log("component die");
    }
    render() {
      console.log("render");
      return <div>
        <h1>count : {this.state.count}</h1>
        <button onClick={this.add}>plus</button>
        <button onClick={this.minus}>Minus</button>
        </div>
    }
    
  }

  export default App;

mounting - 생성

  • 리액트가 생길 때 호출
  • constructor()
    • 생성자, 자바스크립트에서 사용되는 개념.
    • 클래스가 생성하자마자 실행하게 되는 함수.
  • render()
    • 컴포넌트를 화면에 렌더링.
  • componentDidMount()
    • 컴포넌트가 처음 렌더링 되었을 때 실행.
  • constructor → render → constructor 순서

updating - 수정

  • setState() 호출 시 호출
  • render()
  • componentDidUpdate()
  • render → componentDidUpdate 순서

unmounting - 삭제

  • 페이지를 바꾸거나, state가 변하거나 해서 컴포넌트가 죽을 때
  • componentWillUnmount()

컴포넌트

import React from 'react';

  class App extends React.Component {
    state = {
      isLoading: true
    }
    componentDidMount() {
      setTimeout(() => {
        this.setState({isLoading : false});
      }, 3000);
    }
    render(){
      const {isLoading} = this.state;
      return <div>
        <h1>{isLoading ? "Loading" : "Ready"}</h1>
      </div>;
    }
  }

  export default App;
  • setTimeout()
    • 두번째 인자에 밀리초가 지나면 첫번째 인자 실행?
  • state의 속성 이름만 알면 변수로 선언 가능.
    • this.state.isLoading == const {isLoading} = this.state
  • state에 모든 요소를 미리 선언할 필요는 없다. 도중에 추가해도 괜찮.

#4

fetch API

  • 자바스크립트에서 데이터를 fetch하는 방법
    • fetch
    • axios

axios와 fetch의 차이점
axios, fetch, ajax

  • axios는 fetch 위에 있는 작은 layer다.
  • npm i axois
  • YTS에서 API 사용할 것.
import React from 'react';
  import axios from "axios";

  class App extends React.Component {
    state = {
      isLoading: true
    }
    getMovies = async() => {     //async getMovies()
      const movies = await axios.get("https://yts-proxy.now.sh/list_movies.json");
    }
    componentDidMount() {
     this.getMovies();
    }
    render(){
      const {isLoading} = this.state;
      return <div>
        <h1>{isLoading ? "Loading" : "Ready"}</h1>
      </div>;
    }
  }

  export default App;
  • axios가 끝날 때까지 기다리려 하기에 async로 비동기로 만듬.
    • axios가 끝날 때까지 기다릴 것.

API에서 값 뽑아오기

import React from "react"
import PropTypes from "prop-types"

function Movie({ id, year, title, summary, poster }) {
  return <h4>{title}</h4>;
}

Movie.propTypes = 
{
    id: PropTypes.number.isRequired,
    title: PropTypes.string.isRequired,
    summary: PropTypes.string.isRequired,
    poster: PropTypes.string.isRequired,
    year: PropTypes.number.isRequired

};

export default Movie;
  • movie.js
  • propTypes로 자료 검사
    • 함수는 propTypes, 안에서는 PropTypes?
import React from 'react';
import axios from "axios";
import Movie from './movie';

  class App extends React.Component {
    state = {
      isLoading: true,
      movies: []
    }
    getMovies = async() => {     //async getMovies()
      const {data: {data :{movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json?sort_by=rating");
      this.setState({movies, isLoading: false});
    }
    componentDidMount() {
     this.getMovies();
    }
    render(){
      const {isLoading, movies} = this.state;
      return <div>
        <h1>{isLoading ? "Loading" : movies.map(movie => {
          console.log(movie);
          return <Movie
					key={movie.id}
          id={movie.id}
          title={movie.title}
          year={movie.year}
          summary={movie.summary}
          poster={movie.medium_cover_image}
          />
        })}</h1>
      </div>;
    }
  }

  export default App;
  • App.js
  • movie.js 파일의 Movie 컴포넌트를 가져와서 리턴할 때 호출.
  • props으로 갈 정보들에는 무조건 고유한 key 가 있어야 한다?

뽑아온 자료 배치하기

import React from 'react';
  import axios from "axios";
import Movie from './movie';

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

  export default App;
  • App.js
import React from "react"
import PropTypes from "prop-types"

function Movie({ id, year, title, summary, poster }) {
  return <div class="movies__movie">
      <img src={poster} alt={title} title={title}/>
      <div class="movie__data">
      <h3 class="movie__title">{title}</h3>
      <h5 class="movie__year">{year}</h5>
        <p class="movie__summary">{summary}</p>
      </div>

      
  </div>;
}

Movie.propTypes = 
{
    id: PropTypes.number.isRequired,
    title: PropTypes.string.isRequired,
    summary: PropTypes.string.isRequired,
    poster: PropTypes.string.isRequired,
    year: PropTypes.number.isRequired

};

export default Movie;
  • movie.js

리액트에서 스타일 주기

  • 스타일 컴포넌트를 사용해서 스타일을 줄 수 있다.
  • HTML 태그에 style={{}} 형태로 줄 수 있다.
  • css 파일을 만들어서 id, class로 관리할 수 있다.

장르 추가

  • jsx에서 class를 사용하면 실제 클래스와 혼란스러울 수 있기 때문에 className으로 바꿔줘야 한다.
  • label의 태그인 for가 자바스크립트에서는 반복문 for로 인식되기 때문에 htmlFor로 사용해야 한다.
import React from 'react';
  import axios from "axios";
import Movie from './movie';
import "./App.css"

  class App extends React.Component {
    state = {
      isLoading: true,
      movies: []
    }
    getMovies = async() => {     //async getMovies()
      const {data: {data :{movies}}} = await axios.get("https://yts-proxy.now.sh/list_movies.json?sort_by=rating");
      this.setState({movies, isLoading: false});
    }
    componentDidMount() {
     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}
                title={movie.title}
                poster={movie.medium_cover_image}
                summary={movie.summary}
                year={movie.year}
                genres={movie.genres}
              />
            ))}
          </div>
        )}
      </section>
    );
  }
}

  export default App;
  • App.js
import React from "react"
import PropTypes from "prop-types"
import "./movie.css"
function Movie({ id, year, title, summary, poster, genres }) {
  return <div className="movies__movie">
      <img src={poster} alt={title} title={title}/>
      <div className="movie__data">
      <h3 className="movie__title">{title}</h3>
      <h5 className="movie__year">{year}</h5>
      <ul className="genres">
        {genres.map((genre, index) => (
        <li key={index}className="movie__genres">{genre}</li>))}
            </ul>
        <p className="movie__summary">{summary}</p>

      </div>

      
  </div>;
}

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

};

export default Movie;
  • movie.js
  • map 함수는 현재의 item, item의 번호를 인자로 제공한다.

텍스트 자르기

  • 문자열.slice(시작위치, 종료위치)

문자열 저장

  • gh-pages

    • npm i gh-pages

    • 깃허브에 업로드하는 것을 허가해주는 모듈

    • 웹사이트를 깃허브의 깃허브 페이지 도메인에 나타나게 해준다.

      {
        "name": "react_movie",
        "version": "0.1.0",
        "private": true,
        "dependencies": {
          "@testing-library/jest-dom": "^5.14.1",
          "@testing-library/react": "^11.2.7",
          "@testing-library/user-event": "^12.8.3",
          "axios": "^0.21.1",
          "gh-pages": "^3.2.3",
          "prop-types": "^15.7.2",
          "react": "^17.0.2",
          "react-dom": "^17.0.2",
          "react-scripts": "4.0.3",
          "web-vitals": "^1.1.2"
        },
        "scripts": {
          "start": "react-scripts start",
          "build": "react-scripts build",
          "test": "react-scripts test",
          "eject": "react-scripts eject",
          "deploy": "gh-pages -d build",
          "predeploy": "npm run build"
        },
        "eslintConfig": {
          "extends": [
            "react-app",
            "react-app/jest"
          ]
        },
        "browserslist": {
          "production": [
            ">0.2%",
            "not dead",
            "not op_mini all"
          ],
          "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
          ]
        },
        "homepage": "https://gulsam00.github.io/react_movie/"
      }
  • package.json

  • 업로드를 위해 package.json에서 homepage를 설정해준다.

    • "homepage": "git remote add origin [https://github.io/GulSam00/react_movie.git](https://github.io/GulSam00/react_movie.git)"
  • script에 "deploy": "gh-pages -d build" 를 추가한다.

  • script에 "predeploy" : "npm run build" 를 추가한다.

  • npm build 시 build 폴더가 추가된다.

  • npm run deploy로 실행한다.

    • predeploy가 먼저 호출된 후, 이후 deploy를 호출한다.
  • 주소 : https://`깃허브id`.github.io/`디렉토리 이름`

'react-scripts'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. 시 npm update

정리

  • state를 갖기 위해 React.Component에서 extends 할 필요 없다.
    • react hook에 대해 검색

보너스 - 반응형 만들기

라우터

  • 조건에 따라 특정 페이지로 보내주는 역할을 한다.
  • react-router-dom
    • 네비게이션을 만들어주는 패키지
import React from 'react';
import {HashRouter, Route} from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About"

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

export default App;
  • Route 컴포넌트 안에는 렌더링할 스크린, url로 뭘 할건지가 prop으로 들어간다.

  • ? 왜 path에서도 소문자냐? 기준이 뭐지?

    • path : url로 지정할 주소.
  • url의 뒤에 About을 붙이면 해당 페이지로 이동

    • 버튼으로 이용할 여지가 있을 듯
  • 라우터를 여러개 만들면 모두 렌더링하게 된다.

    • url이 일치하는 부분이 있으면 전부 렌더링하게 된다.

    • /home, /home/intro 두 개의 path가 있다면 url이 home/intro 일 시 두 개의 컴포넌트 전부 렌더링하게 된다.

    • exact={true} 시 해당 path만 존재할 시 렌더링하도록 제어할 수 있다.


      네비게이션

      import React from 'react';
      
      function Navigation() {
          return <div>
              <a href="/">Home</a>
              <a href="/about">About</a>
          </div>
      }
      
      export default Navigation;
      
  • html인 href를 사용하면 react임에도 불구하고 페이지를 이동할 때마다 새로고침을 해버린다.

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;
  • Link를 사용 시 훨씬 빠르게 화면을 바꾸게 된다.
  • 모든 화면을 새로고침 하지도 않는다.
  • Link는 라우터 안에서만 사용 가능하다.
  • HashRouter 대신 BrowserRouter를 사용하면 주소에 #이 사라지지만 깃허브 페이지에 설정하는 게 번거롭다.

props 공유

  • props를 console.log로 띄워보면 react-router로 전송받은 4개의 큰 요소가 나온다.
  • 라우터에 있는 모든 라우트들은 기본값으로 props를 가진다.
  • props를 스크린에 띄울 수 있다.
  • Link 사용 시 to에 구조체를 보낼 수 있다.
import React from "react"
import PropTypes from "prop-types"
import "./movie.css"
import {Link} from "react-router-dom"

function Movie({ id, year, title, summary, poster, genres }) {
  return (
  <Link to={{
    pathname: "/movie-detail",
    state: {
     year,
     title,
     summary,
     poster,
     genres
    }
  }}
  >
 <div className="movies__movie">
      <img src={poster} alt={title} title={title}/>
      <div className="movie__data">
      <h3 className="movie__title">{title}</h3>
      <h5 className="movie__year">{year}</h5>
      <ul className="genres">
        {genres.map((genre, index) => (
        <li key={index}className="movie__genres">{genre}</li>))}
            </ul>
        <p className="movie__summary">{summary.slice(0, 140)}... <button>see more</button></p>

      </div>
  </div>
  </Link>
);
}

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

};

export default Movie;
  • movie.js
  • Link의 to의 state 옵션에 전달하려는 값을 넣는다.
import React from 'react';

function Detail(props){
    console.log(props);
    return <h1>Hello!</h1>;
}

export default Detail;
  • Detail.js

리다이렉트

  • 컴포넌트를 클릭하지 않고 url로 넘어왔을 시 다시 홈 화면으로 돌아가게끔 해야 한다.
import React from 'react';

class Detail extends React.Component {
    componentDidMount(){
        console.log(this.props);
        const {location, history} = this.props;
        if (location.state === undefined){
            history.push("/");
        }
    }
    render(){
        const {location} = this.props;
        if (location.state)
        {
            return <span>{location.state.title}</span>;
        }
        else {
            return null;
        }
               
    }
}

export default Detail;
  • props가 전달되지 않을 시 홈화면으로 돌아가게끔 한다.
profile
씨앗 개발자

0개의 댓글