Hello ReactWorld - 6 redux

hanana·2023년 11월 21일
0

반가워React

목록 보기
6/10
post-thumbnail

본 포스팅은 코딩애플님의 리팩트 강의를 수강한 후 참고하여 작성하였습니다.

[서론]

강의를 진행하면서
자식요소가 부모요소의 state를 사용하기 위해선 props로 전달을 해야하고
자식의 자식요소가 해당 state를 사용하기 위해선 또 props로 전달을 하면서
뭔가 굉장히 귀찮은 듯한 과정이 이루어진다.
이를 해결하기 위한 방법에 대해 알아보자

Context API

리액트 기본문법 -- 실전에서는 거의 사용하지 않음

문제점
1. 성능이슈
2. 컴포넌트 재활용이 어려움

대충 이런게 있다.. 정도로만 알고 넘어가자
나중에 레거시에서 발견되면 그때 찾아보자...
배울게 많다...


Redux

컴포넌트들이 props 없이 state 공유가 가능하게 해주는 리액트 라이브러리

개요
1. js파일 한개에 state를 다 보관하고
2. 모든 컴포넌트는 원하는 state 꺼내쓸 수 있는 개념
* 보관하는 어떠한 저장소를 store라고 부름
3. 리액트 구인시 대부분 Redux 요구

리액트 18.1 이상의 버전을 요구한다.

1. 설치

npm install @reduxjs/toolkit react-redux

2. 세팅1
src경로 밑에 store.js파일을 생성 후 설정파일 복붙

import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
  reducer: { }
}) 

3. 세팅2
index.js에 가서 <Provider store = {store}> 추가

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

Redux - store에 I/O 하기

store.js

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


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


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

해당 요소를 사용할 js

import { useSelector } from 'react-redux';
const Cart = () => {
let state = useSelector((state) => {
  return state
})
console.log(state.user);

// 생략
  • 1. createSlice 함수를 통해서
    초기화를 해준다. 예제에서는 간단히 user : kim 이라는 간단한 데이터를 주었다.
  • 2. reducoer 함수를 통해서 store에 저장한다.
  • 3. useSelector 함수를 통해서 저장된 state를 불러온다.
    state 변수에는 저장한 모든 state가 들어가있다.

[주의]

그렇다고 Redux store안에 모든걸 넣지 맙시다!
간단한 애플리케이션의 경우 오히려 코드를 설정하는부분,
라이브러리를 설치하는 부분에서 반드시 Redux가 좋다고만은 할 수 없다고 함.


Redux - store의 state 변경하기

  • 1. state 수정해주는 함수 작성
  • 2. 해당 함수를 export, import
  • 3. dispatch를 이용해서 state 변경을 store.js에 요청하기

간단한 예제코드로 정리해보자
store.js

let user = createSlice({
    name : 'user',
    initialState : 'hana',
    // STEP1. 함수 작성하기
    reducers : {
      changeName(state) {
        return 'babo ' + state
      }
    }
})
//STEP2. 함수 export 하기
export let {changeName} = user.actions

reducers 안쪽에changeName() 이라는 함수를 만들고
해당 함수를 호출하면 기존의 state를 return 값으로 바꿔준다.
현재 해당함수를 호출하면 'hana' 라고 저장된 state가 'dev hana' 로 변경

사용할 페이지

// STEP3. 임포트하기
import { useDispatch, useSelector } from 'react-redux';
import { changeName} from "./../store.js";
// 생략


// STEP3. [중요] useDispatch 함수를 사용해서 함수를 변경해야 함
let dispatch = useDispatch()
  
  
return (
<div>
<button onClick={() => {
  //STEP3. dispatch(changeName())
  dispatch(changeName())
}}>+</button>
</div>
)

Redux - store의 state가 array인 경우

let user = createSlice({
  name : 'user',
  initialState : {name : 'hana', age: 25},
  
  reducers : {
    changeName(state) {
      return {name : 'babo ' + state.name, age: 25}
    }
  }
})

이렇게 바꿀수도 있지만

let user = createSlice({
  name : 'user',
  initialState : {name : 'hana', age: 25},
  
  reducers : {
    changeName(state) {
      state.name = 'babo ' + state.name
    }
  }
})

이라는 형태로도 변경이 가능하다.

또한 store의 상태변경 함수에 파라미터를 담을수도 있는데

let user = createSlice({
  name : 'user',
  initialState : {name : 'hana', age: 25},
  
  reducers : {
    addAge(state, age) {
      state.age += age.payload;
    }

  }
})

함수의 두번째인자.payload 를 통해서 넘겨온 값을 사용할 수 있다.
해당 함수의 사용부는 아래와 같다.

<button onClick={()=> {
  dispatch(addAge(1)) // 파라미터로 1 전송
}}>나이먹기싫다</button>

상태변경하는 방법이 조금 복잡한 이유

너무 어렵게 생각하지 말고 자바에서 setter를 함부로 사용하면 안되는 이유와 비슷하다!


여러 컴포넌트에서 state를 공유해서 사용하고
각각의 component에서 state를 변경할 수 있다면
state 데이터에 이상이 생겼을때
어디서 이상한 값이 들어왔는지 확인하기 위해서 모든 commponent를 찾야아 하는 수고로움이 있다.


반대로 store에서만 데이터를 변경가능하고
해당 함수를 제공해서 사용하게 하면
데이터에 문제가 생겼을때 높은확률로 store 내부의 함수만 찾아보면 되므로 디버깅이 쉬워진다.

profile
성숙해지려고 노력하지 않으면 성숙하기까지 매우 많은 시간이 걸린다.

0개의 댓글