본문 바로가기
웹/24-StudyWithPnP

[React+JS/리액트] 웹 스터디 8주차

by 보먀 2024. 6. 12.
728x90
반응형

Redux -1

  • 여러 컴포넌트가 공유하는 상태 관리를 자바스크립트 상태관리 라이브러리
  • 리액트와 사용하기 위해서는 RTK(React Tool Kit) 설치 필요

 

redux 를 사용하면 props 없이 state를 공유할 수 있게 해준다. 자바스크립트 파일을 하나 만들어서 state 들을 보관하고 모든 컴포넌트들은 자바스크립트 파일 안에 있는 state 들을 직접 꺼내쓸 수 있다. 

 

프로젝트 사이즈가 커져서 컴포넌트가 많아졌을 때 사용하기 좋다. 그래서 요즘은 개발자 구인시에도 redux 같은 라이브러리의 숙련도를 대부분 요구한다고 한다.

 

 

- redux toolkit 설치

 

redux 사용을 위해 터미널에서 아래와 같이 입력

 redux toolkit 설치시 npm install @reduxjs/toolkit@1.8.1 react-redux

 

redux toolkit 이라는 라이브러리는 redux 개선 버전이라고 생각하면 된다. (문법이 쉬워짐)

 

설치 시 주의사항은 pakage.json 파일을 열어서 아래의 항목을 확인해봐야 한다. 둘 다 18.1.x 이상의 버전일 경우에만 사용 가능하다.

버전이 낮은 경우는 아래 사진과 같이 파일을 수정한 후에 설치하면 된다. 

 

 

- Redux 셋팅

 

셋팅1. store.js 파일 생성 & 코드 넣어주기

 

src 폴더 안에 파일을 만들고 아래의 코드를 파일에 붙여넣어준다. 이 파일은 state 를 보관할 파일이다. 

// store.js
import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: { }
})

 

 

셋팅2. index.js 파일로 가서 <Provider store={store}> 로 App 감싸주기

 

store.js 를 import 해오고 Provider 로 <App /> 을 감싸준다. 이렇게 하면 <App /> 과 그 모든 자식 컴포넌트들은 store.js 에 있던 state 를 맘대로 꺼내쓸 수 있다. 

import { Provider } from "react-redux";
import store from './store.js'

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
);

 

 

Redux -2 

 

- Redux store 에 state 보관하는 법

 

1. createSlice() 로 state 만들기

2. configureStore() 안에 state 등록

 

// store.js
import { configureStore, createSlice } from '@reduxjs/toolkit'

let user = createSlice({
  name : 'user',
  initialState : 'kim'
})

export default configureStore({
  reducer: {
    user : user.reducer
  }
})

 

createSlice() 상단에서 import 해온 다음에

{ name : 'state 이름', initialState: 'state값' } 형식으로 값을 넣으면 state 생성이 가능하다.

 

state 등록은 configureStore() 안에 하면 되는데, 

{ 작명 : createSlice만든거.reducer } 형식으로 등록해주면 된다. 

 

이렇게 등록한 state 는 모든 컴포넌트가 자유롭게 사용이 가능하다!

 

 

- Redux store 에 있던 state 가져다쓰는 법

// Cart.js

import { useSelector } from "react-redux"

function Cart(){
  let a = useSelector((state) => { return state } )
  console.log(a)

  return (생략)
}

 

useSelector 를 import 하고, useSelector((state) => { return state }) 를 쓰면 store 에 있던 모든 state 가 그 자리에 남게된다. 

변수에 저장해서 출력해보면 모든 state 가 출력되는 것을 확인할 수 있다. 

 

 

※ 참고1

 

중괄호와 리턴문을 벗겨내고 아래처럼 간단하게 써도 된다.

let a = useSelector((state) => state.user )

 

 

※ 참고2 

 

그럼 props 말고 앞으로 redux 를 쓰는 것이 더 괜찮은 방법? (X)

-> 컴포넌트가 많을 땐 redux 를 쓰는 것이 편리하지만, 컴포넌트가 몇 개 없을 때는 그냥 props 를 쓰는 것이 코드가 더 간결하다.

 

 

숙제: store.js 에 state 를 만들고 Cart.js 에 가져와서 데이터바인딩 해보기

// store.js

import { configureStore, createSlice } from '@reduxjs/toolkit'

let cart = createSlice({
    name: 'cart',
    initialState: [
        {id : 0, name : 'White and Black', count : 2},
        {id : 2, name : 'Grey Yordan', count : 1}
      ] 
})

export default configureStore({
    reducer: {
        cart: cart.reducer
    }
})
// Cart.js

import {Table} from 'react-bootstrap'
import { useDispatch, useSelector } from "react-redux"

function Cart() {

    let state = useSelector((state)=>{ return state })
    
    return (
        <div>
            <Table>
                <thead>
                    <tr>
                        <th>#</th>
                        <th>상품명</th>
                        <th>수량</th>
                        <th>변경하기</th>
                    </tr>
                </thead>
                <tbody>
                    {   // 반복문 쓸 때 key 속성 추가하면 좋다
                        state.cart.map((a, i) => 
                            <tr key={i}>
                                <td>{i}</td>
                                <td>{state.cart[i].name}</td>
                                <td>{state.cart[i].count}</td>
                                <td></td>
                            </tr>
                        )
                    }
                </tbody>
            </Table> 
        </div>
    )
}

export default Cart

 

 

Redux -3

 

state 변경하는 법

1. store.js 안에 state 변경 함수 만들기

2. state 변경 함수 export 

3. 원할 때 import 하고, dispatch() 로 감싸서 사용

 

 

- store.js 안에 state 변경 함수 만들기

 

reducers : { } 열고 안에 state 변경 함수를 만들면 된다. 

함수 이름은 원하는 대로 작명해주고, 기존의 state 를 사용하고 싶을 때는 state 파라미터를 넣어 사용할 수 있다.

changeName() 을 사용하면 'kim' -> 'john kim' 으로 state 가 변한다.  

let user = createSlice({
  name : 'user',
  initialState : 'kim',
  reducers : {
    changeName(state){
      return 'john ' + state
    }
  }
})

 

 

 

- state 변경 함수 export 

 

다른 컴포넌트에서 사용할 수 있도록 export 해줘야 한다. store.js 파일 밑에 아래와 같이 적어서 export 해주면 된다.

이렇게하면 변수에 state 변경함수들이 남는다. (state 변경함수들을 변수에 저장했다가 export 하는 것!)

export let { changeName } = user.actions

 

 

여러 개를 export 하고 싶을 때는 그냥 괄호 안에 여러 개 적어주면 된다. 

export let { 함수1, 함수2, ... } = user.actions

 

 

 

- 원할 때 import 하고 dispatch() 로 감싸서 사용

 

changeName 이라는 state 변경함수를 import 해오고 store.js 에 state 변경 요청을 보내주는 useDispatch 함수를 변수에 담고 담은 변수로 state 변경함수를 감싸서 사용하면 된다. 

// Cart.js

import { useDispatch, useSelector } from "react-redux"
import { changeName } from "./../store.js"


let dispatch = useDispatch()

(생략) 

<button onClick={()=>{
  dispatch(changeName())
}}>버튼임</button>

 

 

 

사용방법을 간단하게 정리하자면

state 변경함수를 store.js 에 만들어두고 state 를 수정하고 싶은 컴포넌트는 state 변경함수를 불러 state 수정한다.

 

조금 복잡하게 느껴질 수도 있지만, 생각해보면 좋은 방식인 것을 알 수 있다. 예를 들어보자.

 

1. 컴포넌트가 state 를 직접 변경하는 방식

여러 컴포넌트들이 store.js 에 있는 kim 이라는 state 를 직접 수정해서 쓰고 있다. 그러다가 kim 에 이상한 값이 들어가는 버그가 났다. --> 모든 컴포넌트들이 직접 state 를 수정했기 때문에 모든 컴포넌트를 뒤져서 버그가 난 곳을 찾아야 함

 

2. 컴포넌트가 state 변경함수를 불러 state 를 수정하는 방식

여러 컴포넌트들이 store.js 에 있는 kim 이라는 state 를 수정할 때 store.js 에 정의되어 있는 state 변경함수를 불러서 state 변경을 요청하여 사용하고 있다. 위와 같이 kim 에 이상한 값이 들어가는 버그났다. 

-> 실제로 state 변경함수를 실행하는 store.js 만 확인하면 됨

 

그래서 프로젝트의 사이즈가 커질수록 이렇게 코드를 짜는 것이 좋다. 

 

 

728x90
반응형