본문 바로가기
React

리액트 기초 3강 정리

by imagineer_jinny 2021. 4. 16.

라우팅이란

 

-SPA?

Single Page Application! 말 그대로 서버에서 주는 html이 1개 뿐인 어플리케이션이에요.

전통적인 웹사이트는 페이지를 이동할 때마다 서버에서 html, css, js(=정적자원들)을 내려준다면,

SPA는 딱 한번만 정적자원을 받아옵니다.

 

SPA는 주소를 어떻게 옮길 수 있을까?

html은 딱 하나를 가지고 있지만, SPA도 브라우저 주소창대로 다른 페이지를 보여줄 수 있어요.

이렇게 브라우저 주소에 따라 다른 페이지를 보여주는 걸 라우팅이라고 부릅니다.

 

어떻게 구현?  라우팅 라이브러리를 쓰자!

 

 

라우팅 처리하기

 

-react-route-dom 패키지 설치하기

yarn add react-router-dom

React Router: Declarative Routing for React.js

 

React Router: Declarative Routing for React

Learn once, Route Anywhere

reactrouter.com

 

라우터 쓸때는 패키지 깔고 얘넬 복사해주면 되는구나

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";

as는 별명을 지정해주는 친구.

BrowserRouter를 줄여서 Router라고 부를게!

 

공식문서 보고 감잡기. 라우터 어떻게 써?

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";

// This site has 3 pages, all of which are rendered
// dynamically in the browser (not server rendered).
//
// Although the page does not ever refresh, notice how
// React Router keeps the URL up to date as you navigate
// through the site. This preserves the browser history,
// making sure things like the back button and bookmarks
// work properly.

export default function BasicExample() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <Link to="/dashboard">Dashboard</Link>
          </li>
        </ul>

        <hr />

        {/*
          A <Switch> looks through all its children <Route>
          elements and renders the first one whose path
          matches the current URL. Use a <Switch> any time
          you have multiple routes, but you want only one
          of them to render at a time
        */}
        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/dashboard">
            <Dashboard />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

// You can think of these components as "pages"
// in your app.

function Home() {
  return (
    <div>
      <h2>Home</h2>
    </div>
  );
}

function About() {
  return (
    <div>
      <h2>About</h2>
    </div>
  );
}

function Dashboard() {
  return (
    <div>
      <h2>Dashboard</h2>
    </div>
  );
}

1. 일단 브라우저라우터로 다 감싸줘야한다.

2. 감싸준 다음엔? Router, Switch라는 친구 통해서 감싸줘서 누를때마다 이동하면 되겠구나 라고 생각하기

 

리액트에서 라우팅 처리하기 (2)

페이지를 전환해보자!

(1) index.js에 BrowserRouter 적용하기

어떻게 시작?

패키지에서 BrowserRouter 불러오는 것 부터 시작!

(2) 세부 화면 만들기

(3) App.js에서 Route 적용하기

 

Route 사용방법 1: 넘겨줄 props가 없을 때

<Route path="주소[/home 처럼 /와 주소를 적어요]" component={[보여줄 컴포넌트]}/>

Route 사용방법 2: 넘겨줄 props가 있을 때(우리 버킷리스트 앱은 App.js에서 list를 props로 넘겨주죠! 그럴 땐 이렇게 쓰면 됩니다!)

<Route path="주소[/home 처럼 /와 주소를 적어요]" render={(props) => (<BucketList list={this.state.list} />)} />

지금은 넘겨줄 프롭스가 없으니 사용방법1을 씀

import React from 'react';
import logo from './logo.svg';
import './App.css';
// Route를 먼저 불러와줍니다.
import { Route } from "react-router-dom";

// 세부 페이지가 되어줄 컴포넌트들도 불러와주고요!
import Home from "./Home";
import Cat from "./Cat";
import Dog from "./Dog";

class App extends React.Component {

  constructor(props){
    super(props);
    this.state={};
  }
  
  render(){
    return (
      <div className="App">
        {/* 실제로 연결해볼까요! */}
        <Route path="/" component={Home} />
        <Route path="/cat" component={Cat} />
        <Route path="/dog" component={Dog} />
      </div>
    );
  }
}

export default App;

/랑 /cat은 다르지만 컴퓨터는 /(홈화면)과 cat을 같이 보여준다고 생각함.

이걸 중복됬다고 말한다. /가 두개가 중복되서 그럼

이걸 처리하는 방법.

"중복 주소 처리한다"라고 부름.

 

나는 /cat 했을 때 고양이 화면만 보여주고 싶은데 어떡하지? 이때 exact를 쓴다~

(4) exact 적용하기

(5) URL 파라미터사용하기

페이지의 주소값을 보고 어떤걸 띄워주겠다 할 수 있음. 

 

→ 파라미터: /cat/nabi

→ 쿼리: /cat?name=nabi

 

(6) 링크 이동 시키기

매번 주소창을 찍고 페이지를 돌아다닐 순 없겠죠! react-router-dom으로 페이지를 이동하는 방법을 알아봅시다!

1)<Link/> 사용하기

<Link/> 사용 방법

링크 컴포넌트는 html 중 a 태그와 비슷한 역할을 해요. 리액트 내에서 페이지 전환을 도와줍니다.

<Link to="주소">[텍스트]</Link>

App.js에 메뉴를 넣어보자!

링크 컴포넌트 먼저 불러오고 링크 생성해주기

import React from 'react';
import logo from './logo.svg';
import './App.css';
// Route를 먼저 불러와줍니다.
// Link 컴포넌트도 불러왔어요.
import { Route, Link } from "react-router-dom";

// 세부 페이지가 되어줄 컴포넌트들도 불러와주고요!
import Home from "./Home";
import Cat from "./Cat";
import Dog from "./Dog";

class App extends React.Component {

  constructor(props){
    super(props);
    this.state={};
  }
  
  render(){
    return (
      <div className="App">
        <div>
          <Link to="/">Home으로 가기</Link>
          <Link to="/cat">Cat으로 가기</Link>
          <Link to="/dog">Dog으로 가기</Link>
        </div>

        <hr />
        {/* 실제로 연결해볼까요! */}
        <Route path="/" exact component={Home} />
        <Route path="/cat" component={Cat} />
        <Route path="/dog" component={Dog} />
      </div>
    );
  }
}

export default App;

 

2) history 사용하기

Link 컴포넌트를 클릭하지 않고, 조금 더 함수를 사용한 페이지 전환 방법을 알아봅시다!

 

withRouter

You can get access to the history object’s properties and the closest <Route>'s match via the withRouter higher-order component. withRouter will pass updated match, location, and history props to the wrapped component whenever it renders.

 

React Router: Declarative Routing for React.js

 

React Router: Declarative Routing for React

Learn once, Route Anywhere

reactrouter.com

 


Quiz_버킷리스트에서 상세페이지 만들고 이동해보기

 

뭐부터 해줘? 패키지설치!!!!!!!!

yarn add react-router-dom

1. Detail.js만들기

2. index.js가서 브라우저 라우터 불러와주기

(혼자할때 App.js가서 불렀더니 에러뜸... 앱 전체를 감싸줘야하기 때문에 index.js로 간거구나)

3. App.js가서 뭘 import해와야하지?

 

Route, Detail

4. 이제 내려가서 어디에 Route를 연결해줘야 하는지 찾아보기.

버킷리스트 부분만 다르구나! 

근데 라우트 쓰는 두가지 방법이 있었네?

위에 적은 1)컴포넌트 방법이랑 2)render 방식이 있었는데 여기서는 render를 써보자

5. 중간에 화면 가서 잘 나오는지 확인해주고

6. 다시 돌아와서 하나 눌렀을 때 넘겨주는거 해보기

어떻게?

온클릭에다 히스토리 써보는 거 해보자!

7. 히스토리 넘겨주려면 withRouter 가져와주기. 그리고 밑에 감싸주기

8. 감싸주고 리스트 넘긴 곳에다 똑같이 히스토리도 넘겨준다.

9. 버킷리스트 페이지 와서 콘솔 잘 찍히는지 확인

10. 히스토리 잘 찍힌 걸 볼 수 있음. 그럼 얘를 눌렀을 때 뭘 해주면 된다?

push해주면 되겠다! 어디로? Detail로!!

11. 이후 리스트 하나 누르면 상세페이지로 가는 것 확인!


라우팅, 조금 더 꼼꼼히 쓰려면?

 

- 잘못된 주소 처리하기

exact로 중복 주소를 처리하는 방법은 이미 배웠습니다! 이번엔 우리가 미리 정하지 않은 주소로 들어온 경우를 다뤄볼게요. (저는 버킷리스트 프로젝트에서 진행합니다!)

 

1) NotFound.js 파일을 만들고 빈 컴포넌트를 만들기

2)App.js에서 불러오기

3)Switch 추가

4)NotFound 컴포넌트를 Route에 주소 없이 연결해주기.

Switch는 어떻게 사용?

라우트 바깥에다가 감싸주면 됨

감싸주고 라우트 하나 추가해서 path가 지정되지 않은 페이지를 하나 연결해주면 끝남

 

즉, 없는 주소 처리를 하려면 Switch로 감싼 다음에 그 안에다가 라우트로 path를 넘겨주지 않으면 

path가 지정되지 않은 모든 주소는 여기로 빠진다라고 생각하면 됨!

 

 

-뒤로가기 버튼 만들어주기 

 

1. App.js에서 Route 손봐주기

2. NotFound.js에 버튼 만들어주기 

바로 버튼 만들면 안되고 <div>로 감싸준다음에 만들기

 

 

리덕스란?

 

상태 관리를 편하게 해줌! 

 

즉, 컴포넌트의 데이터를 관리하는 방법에 대한 내용라우팅이란

 

우리한텐 이미 컴포넌트의 데이터를 관리해주는 state와 props가 있지만 이런 부모, 자식 관계가 약간은 불편할 수도 있다는 것을 깨달아버림. 그래서 전역으로 하는 상태 관리가 필요함을 느낌.

 

리덕스 패키지 설치

yarn add redux react-redux

왜 두개를 깔지?

리액트에서 리덕스를 쓰는거랑 리덕스라는거랑 따로 있는거구나!

 

리덕스라는 것은 완전히 별개의 패키지임. 

한마디로 리액트를 쓰지 않아도 리덕스를 사용할 수 있음.

 

리액트 리덕스는 리액트랑 리덕스를 연결해주는 친구.

 

공식문서를 확인해보자

Redux 시작하기 | Redux

 

Redux 시작하기 | Redux

소개 > 시작하기: Redux를 배우고 사용하기 위한 리소스

ko.redux.js.org

리덕스에 제일 기본이 되는 개념은 '전역 상태 관리'

부모->자식으로 흐르는 데이터를 한 군데에서 즉, 이 부모와 자식과 동떨어진 데에 넣어두겠다는 소리!

동떨어진 데에 넣어두고 필요할때마다 얘네가 수정해줘 라고 요청을 보낸다던가 아니면 나 이거 데이터좀 줘봐 하면서 

여기서 이렇게 꺼내다가 쓰겠다라는 소리임.

그럼 여기저기서 꺼내다 쓸 수 있죠.

한마디로, 전역으로 저장해놓은 어떤 데이터 모음들을 아무 데서나 참조하겠다 라고 말할 수 도 있음!

 

1)State

리덕스에서는 저장하고 있는 상태값("데이터"라고 생각하셔도 돼요!)를 state라고 불러요. 딕셔너리 형태({[key]: value})형태로 보관합니다.

전역으로 갖고 있는 데이터가 State구나 라고 생각하면 편함!

 

2)Action

상태에 변화가 필요할 때(=가지고 있는 데이터를 변경할 때) 발생하는 것입니다.

// 액션은 객체예요. 이런 식으로 쓰여요. type은 이름같은 거예요! 저희가 정하는 임의의 문자열을 넣습니다.
{type: 'CHANGE_STATE', data: {...}}

3)ActionCreator

액션 생성 함수라고도 부릅니다. 액션을 만들기 위해 사용합니다.

액션을 리턴해주는 함수!

//이름 그대로 함수예요!
const changeState = (new_data) => {
// 액션을 리턴합니다! (액션 생성 함수니까요. 제가 너무 당연한 이야기를 했나요? :))
	return {
		type: 'CHANGE_STATE',
		data: new_data
	}
}

4)Reducer

리덕스에 저장된 상태(=데이터)를 변경하는 함수입니다. 우리가 데이터를 바꾸고 싶을 때 순서가 어떻게 되냐면 먼저 컴포넌트들이 데이터를 바꾸고 싶은 순간에  액션 생성 함수를 부르고 → 이 액션 생성 함수가 액션을 반환, 즉 액션을 만들면 → 리듀서가 지금 리덕스에 들어가있는 현재 상태(=데이터)와 액션 객체를 받아서(액션에 타입 들어있었는데 그런 타입을 받고 스위치케이스 안에서 구문을 읽어서 실제로 데이터를 변경하게 됨) → 새로운 데이터를 만들고 → 리턴해줍니다.

 

즉 리듀서는 실제로 데이터를 변경하는데 관여하는 함수이구나!

// 기본 상태값을 임의로 정해줬어요.
const initialState = {
	name: 'mean0'
}

function reducer(state = initialState, action) {
	switch(action.type){

		// action의 타입마다 케이스문을 걸어주면, 
		// 액션에 따라서 새로운 값을 돌려줍니다!
		case CHANGE_STATE: 
			return {name: 'mean1'};

		default: 
			return false;
	}	
}

5)Store

우리 프로젝트에 리덕스를 적용하기 위해 만드는 거예요! 스토어에는 리듀서, 현재 애플리케이션(우리의 프로젝트) 상태, 리덕스에서 값을 가져오고 액션을 호출하기 위한 몇 가지 내장 함수가 포함되어 있습니다. 생김새는 딕셔너리 혹은 json처럼 생겼어요. 내장함수를 어디서 보냐구요? → 공식문서에서요! 😉

 

즉, 스토어는 우리가 데이터를 볼 수 있게 해주는 친구다.

 

6)dispatch

디스패치는 우리가 앞으로 정말 많이 쓸 스토어의 내장 함수예요! 액션을 발생 시키는 역할을 합니다.

컴포넌트들이 리덕스에 들어있는 데이터를 바꾸고 싶으면 어떻게 해야하나?

액션 생성 함수라는 걸 호출을 함! 그 호출을 어떻게 해?

디스패치라는 녀석을 통해서 호출을 할 것임.

액션을 발생시키는 역할을 맡아줌.

// 실제로는 이것보다 코드가 길지만, 
// 간단히 표현하자면 이런 식으로 우리가 발생시키고자 하는 액션을 파라미터로 넘겨서 사용합니다.
dispatch(action); 

 

몰라도 되는, 하지만 알면 재미있는 이야기 리덕스는 사실, 리액트와 별도로 사용할 수 있는 친구입니다. 상태관리를 위해 다른 프론트엔드 프레임워크/라이브러리와 함께 쓸 수 있어요.

 

리덕스의 3가지 특징

 

(1) store는 1개만 쓴다!

리덕스는 단일 스토어 규칙을 따릅니다. 한 프로젝트에 스토어는 하나만 씁니다.

즉, 리덕스를 보는 거는 한 군데만 본다!!!!

 

(2) store의 state(데이터)는 오직 action으로만 변경할 수 있다!

리액트에서도 state는 setState()나, useState() 훅을 써서만 변경 가능했죠! 데이터가 마구잡이로 변하지 않도록 불변성을 유지해주기 위함입니다. 불변성 뭐냐구요? 간단해요! 허락없이 데이터가 바뀌면 안된단 소리입니다!

조금 더 그럴 듯하게 말하면, 리덕스에 저장된 데이터 = 상태 = state는 읽기 전용입니다.

그런데... 액션으로 변경을 일으킨다면서요? 리듀서에서 변한다고 했잖아요? → 네, 그것도 맞아요. 조금 더 정확히 해볼까요! 가지고 있던 값을 수정하지 않고, 새로운 값을 만들어서 상태를 갈아끼웁니다! 즉, A에 +1을 할 때, A = A+1이 되는 게 아니고, A' = A+1이라고 새로운 값을 만들고 A를 A'로 바꾸죠.

 

(3) 어떤 요청이 와도 리듀서는 같은 동작을 해야한다!

리듀서는 순수한 함수여야 한다는 말입니다. 순수한 함수라는 건,

  • 파라미터 외의 값에 의존하지 않아야하고,
  • 이전 상태는 수정하지(=건드리지) 않는다. (변화를 준 새로운 객체를 return 해야합니다.)
  • 파라미터가 같으면, 항상 같은 값을 반환
  • 리듀서는 이전 상태와 액션을 파라미터로 받는다.

리덕스를 통한 리액트 상태 관리

 

-상태 관리! 왜 필요한가?

추가하기 부분을 자식으로 (다른컴포넌트로) 빼면 자식에서 데이터를 부모로 넘겨주지 못해서 리스트 추가가 안된다는 말 같다. 그러니까 결론은 이런게 불편하고 코드도 길어지고(App.js에) 하니까 다른 해결책이 필요하고 그게 리덕스의 상태관리! 데이터를 그냥 한곳에 때려 박고 부모든 자식이든 그 데이터 저장소를 같은 곳을 바라본다면.. 수월할 것이다!

 

-상태 관리 흐름을 알아보자!

(1) 리덕스 Store를 Component에 연결한다.

-컴포넌트는 스토어에서 데이터를 가져다가 볼 수 있다. 이걸 구독한다고 부른다.

혹은 연결해준다고 부른다. 그림에서는 노랑 동그라미랑 초록 동그라미가 

스토어에서 데이터를 구독하고 있는 연결된 친구들임.

 

(2) Component에서 상태 변화가 필요할 때 Action을 부른다.

초록색 친구가 만약에 라이크를 누른다고 했을 때 우리의 스토어에는 데이터가 변해야 함.

이 변함에 대해 액션을 부름. '나 데이터 바꿔줘'라고 호출을 한 것=액션을 부른다 라고 표현!!

 

(3) Reducer를 통해서 새로운 상태 값을 만들고,

그러면 리듀서는 그 액션이 무슨 타입인지 봐야함. 무슨 타입인지 보고 새로운 값을 만들 것임!

만약 라이크를 누른거라면 라이크가 true로 변할 것임!

false였다가 true로 변하던가 하는 식의 어떤 액션을 만드는 것.

 

(4) 새 상태값을 Store에 저장한다.

그리고 값이 true로 변하면 스토어에 있는 값이 어떻게 될까? 변할 것이다.

새 상태값을 스토어에 저장한다고 표현한다.

이렇게 해서 스토어에 새로운 값이 생겼으면,

 

(5) Component는 새로운 상태값을 받아온다. (props를 통해 받아오니까, 다시 랜더링 되겠죠?)

컴포넌트는 새로운 상태 값을 받아올 수 있다. 

스토어는 바뀐 상태값을 컴포넌트들에게(나를 구독하고 있는, 나와 연결된 컴포넌트들에게)

'나 데이터 변했어. 다시 가져가' 하고 알려준다라는 개념.

 

한마디로 우리가 보고 있는 view에 있는 데이터가 바뀌어 담긴 거니까, props로 넘어 올 거니까

그럼 이 컴포넌트들 다시 렌더링 됨.

 

다시,

1. 컴포넌트는 스토어에 있는 데이터를 구독할거고

2. 구독한 다음 나에게 어떤 데이터 변경이 필요한 경우

(사용자가 좋아요를 눌렀다거나 추가하기를 눌렀던 경우에)

'나 바꿔 줘'하고  액션을 부름.

3. 액션을 부르면 리듀서는 데이터를 새로 만들 것임.

리듀서 안에 있는 함수를 실행해서. 혹은 그 안에 있던 연산을 처리

4. 그렇게 새로운 값을 만들고 얘를 스토어에 저장할 것임.

5. 스토어에 새로운 값이 저장이 되면 스토어를 보고 있는 다른 컴포넌트들한테

'나 값이 변했으니까 너 새로운 값 가져가' 라고 말해줄거고 

6. 컴포넌트는 그 새로운 값을 가지고 온다. props로 받아온다.

7.props로 받아와가지고 어떻게 할거다? 다시 렌더링 할거다.

왜? props가 바뀌면 재렌더링이 되니까! 리렌더링!

 

 

-리덕스 써보기

 

리덕스를 사용할 때 일단 Action, Action Creator, Reducer를 포함하는 redux module을 하나 만들거고 

그걸 만든 다음에 store를 만들거임!

 

1. 리덕스 폴더 만들어주기

2. 리덕스 안의 모듈즈 안에 bucket.js 하나 만들기

 

3. 액션 뭐 있는지 프로젝트 화면 돌아가서 보면 일단 리스트가 조회되는 로딩 하나랑

추가하기 버튼을 눌렀을 때 추가하기가 있음.

 

그럼 돌아와서 액션부터 만들어주기

4. 액션 만들었으면 initialState 만들어주기

이니셜 스테이트에 뭐 넣어? 할 수 있는데 페이지 돌아가서 보면 새로고침 하자마자

리스트 세개가 뜸. 이 리스트가 기본 초기값이 될 것임!

5. Action Creator 만들어주자

액션 생성 함수는 뭘 반환해준다? 액션을 반환해줌!

근데 우리 액션 생성 함수를 컴포넌트들에서 불러온다고 했으니까,

컴포넌트에서 불러와야 액션을 만들것임! 그럼 함수 앞에 export를 붙여줌.

여기서 잠깐, exportexport default의 차이?

컴포넌트 만들 때 export default 하면 import할 때 중괄호 없이 가지고 왔음.

그냥 export만 한 애들은 중괄호 안에서 콤마 콤마로 엮어서 사용할 수 있음. 

export default도 여러개 싸면 안됨? 안됨! export default로 내보낼 수 있는 건 파일 당 하나.

 

우리는 Reducer를 export default로 빼낼 거기 때문에 action들은 그냥 export로 빼줌.

 

다시 createBucket으로 돌아가보면 어떤 데이터를 추가해야하는지 헷갈림!이럴때는 미리 만들어놓은 걸 보고 오자App.js의 SendList에 보면 뭘 가지고 리스트에 아이템 하나를 추가해줬지??텍스트 인풋!이 텍스트 인풋에 들어가는 텍스트 값을 가지고 와서 그걸 리스트에 추가해줬음

그럼 다시 버킷으로 돌아가서 

여기 데이터가 뭐가 들어가면 되겠음? 어떤 텍스트가 들어가주면 되겠구나. text라고 치면 뭔지 헷갈리니까 bucket이라고 써주기

그리고 loadBucket같은 경우엔 이미 기본값을 지정해줬기 때문에 처음에 버킷을 안줘도 됨.어떤 데이터를 줄 필요가 없음! 그래도 일단은 버킷을 추가해놓겠음. 아래랑 모양새를 맞춰주고 싶어서 그럼.

6. Reducer 만들어주자

근데 우리 state는 미리 만들어뒀음. initialState그대로 넣어주기.

switch문으로 내려가기.

action.type로 구분하겠다고 하네? action.type은 LOAD. CREATE이런거일것임.

그럼 복사해서 써주자!

이렇게 모듈 하나를 다 만들었다!!

이제 스토어 만들러 가자

 

7. Store 만들기

src 폴더 아래에 redux 폴더 아래에 새 파일.

configStore.js

스토어 만드는 방법 이미 redux에서 제공해주는 것들이 있음

그거 불러와서 쓰기

import {createStore,combineReducers} from "redux";

그리고 우리가 만들었던 모듈 불러와야지

import bucket from "./modules/bucket"; //리덕스 안의 모듈은 소문자로 시작

 

이제 스토어 만들건데 단일 스토어라는 단어 기억함? 

한 프로젝트에는 스토어 하나만 있어야 하고 스토어에는 Reducer 하나만 들어갈 수 있음.

만약 우리가 리듀서를 5개 가지고 있으면 이 다섯개를 하나로 뭉쳐서 넘겨줘야 한다는 소리.

지금 우리는 하나밖에 없지만 뭉치는 방법을 써보겠음.

이렇게 스토어도 다 만들어줬다!!!!

 

리덕스와 컴포넌트를 연결하자!

스토어를 만들어줬는데 얘를 쓰려면 어떻게 해야 하나?

컴포넌트랑 연결을 해야함!

 

index.js에서 필요한 작업을 해줄거예요.

스토어를 불러오고 → 우리 버킷리스트에 주입하면 끝!

 

-컴포넌트에서 리덕스 데이터 사용하기

 

컴포넌트에서 리덕스 액션 사용하는 법!

이제 우리 리덕스가 버킷리스트에 붙었는데, 아직 실감이 안나죠? 실감이 나도록, App 컴포넌트에 붙은 state를 리덕스로 교체해볼까요?

 

1] 클래스형 컴포넌트에서 리덕스 데이터 사용하기

 

1) 리덕스 모듈과 connect 함수를 불러옵니다.

-리덕스 모듈은 우리가 만들었던 거. 액션, 액션크리에이터, 리듀서 들어있는 친구.

커넥트 함수는 뭐야?

컴포넌트랑 리덕스를 연결해주는 친구!

 

App.js에서 임포트 먼저 해주기

리액트리덕스에서 커넥트 먼저 가져오고

import {connect} from "react-redux";

 

2) 상태값을 가져오는 함수와 액션 생성 함수를 부르는 함수를 만들어줍니다.

-디스패치 해주겠다는 소리

커넥트를 하기 위해서는 어떻게 해야 하나?

두개의 함수를 만들어줘야함.

 

1. mapStateToProps

리덕스 스토어에 있는 state 상태값을 props의 형태로 app에 넣어줄 것임

컴포넌트에 넣어주는 친구

state값을 가져와야함. 이 state 값은 스토어에 있는 이니셜 state 같은 상태값. 데이터.

2. mapDispatchToProps

액션이 생긴 것을 감시한다

감시하는 디스패치를 프롭스로 넘겨주는 친구

return 안에는 우리가 만들어줬던 액션 생성 함수를 넣어준다. 

액션을 반환해야 리듀서에서 처리할 수 있게 됨.

import {loadBucket, createBucket} from "./redux/modules/bucket";

3) connect로 컴포넌트와 스토어를 엮어줍니다.

4) 콘솔에 this.props를 찍어봅니다. (스토어에 있는 값이 잘 나왔는지 볼까요!)

어디서 찍나? 

컴포넌트디드마운트에서!

스테이트랑 액션들 잘 들어온 것 확인할 수 있음.

 

5) this.state에 있는 list를 지우고 스토어에 있는 값으로 바꿔봅시다!

6) setState를 this.props.create로 바꿔봅시다!

 

2] 함수형 컴포넌트에서 리덕스 데이터 사용하기

리덕스도 리액트처럼 훅이 있어요. 훅을 사용해서 액션 생성 함수를 불러보고, 스토어에 저장된 값도 가져와 볼게요.

훅은 우리가 편하게 쓰려고 함수로 뭔가를 제공해주고있다는 소리임

 

1) BucketList.js에 useSelector() 적용하기

 

버킷리스트에서 임포트부터 해오기

import {useSelector, useDispatch} from "react-redux";

그 다음에 변수 선언

props 안쓰고도 화면 잘 나오는 것을 확인할 수 있음.

2) 몇 번째 상세에 와있는 지 알기 위해, URL 파라미터를 적용하자

리스트 항목을 누르면 상세페이지입니다 말만 나오고

어떤 상세페이지인지 알 수가 없음.

그래서 누르면 그 내용으로 바뀌게 해주고 싶다!

그러려면 뭘 해야해? 얘가 몇 번째 위치에 있는지 알아야 해!

리스트의 몇 번째에 있는지 알면 디테일에서도 useSelector 사용해서 몇번째 것 해서 가지고 와서 내용

뿌려줄 수 있음.

 

url 파라미터 사용해서 몇번째 상세에 와있는지 알게 하자.

url 파라미터 쓰려면? 일단 App.js로 가

 

라우트 가서 /: 하고 index라고 해보겠음

 <Route path='/detail/:index' component={Detail}/>

받아오는건 어떻게 해?

디테일 페이지 가서 props에 매치 해서 가지고 올 수 있는건데 일단 우리 링크 넘겨주는거니까 링크 넘겨주는거 먼저 고쳐줘야 함. 인덱스 붙여주고

return (
    <ListStyle>
      {bucket_list.map((list, index) => {
        return (
          <ItemStyle key={index} onClick={()=>{props.history.push('/detail/'+index);}}>
            {list}
          </ItemStyle>
   
        );
      })}
    </ListStyle>

주소창 잘 되는 것 확인!

3) 상세페이지에서 버킷리스트 내용을 띄워보자

 

그럼 다시 Detail 페이지로 돌아가서 리덕스 가지고오기.

콘솔 둘다 잘 찍어왔는데

url 보면 인덱스를 문자열로 가지고 오고 있음. url 파라미터는 기본적으로 스트링으로 들어오기 때문인데 

우린 인덱스가 필요하고 숫자형이 필요하니까 스트링을 숫자형으로 바꿔주면 됨 (parseInt)

 

 

Quiz_버킷 리스트 데이터를 삭제해보기

 

1. 삭제하기 버튼 만들어주기

2. 액션, 액션크리에이터, 리듀서 만들어주기

Array.prototype.filter() - JavaScript | MDN (mozilla.org)

 

Array.prototype.filter() - JavaScript | MDN

Array.prototype.filter() filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다. The source for this interactive example is stored in a GitHub repository. If you'd like to contribute

developer.mozilla.org

3. 디스패치 붙여주기

 

댓글