자바스크립트 - React.js

[React.js] 컴포넌트간 편리한 state 공유를 위한 Redux

Lv1_junior_dev 2022. 12. 15. 19:25

❓ Redux

Redux는 props 없이 state를 공유할 수 있게 도와주는 라이브러리입니다.

이거 설치하면 js 파일 하나에 state들을 보관할 수 있는데 그걸 모든 컴포넌트가 직접 꺼내쓸 수 있다. 

그래서 props 전송이 필요 없어지니 컴포넌트가 많아질 수록 좋을듯하다.


❗ Redux 설치

npm install @reduxjs/toolkit react-redux

터미널에 입력하면 된다다. 

redux toolkit이라는 라이브러리는 문법이 쉬워진 redux의 개선버전이다.

 

❗ Redux 셋팅

import { configureStore } from '@reduxjs/toolkit'

export default configureStore({
  reducer: { }
}) 

아무데나 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>
); 

index.js 파일가서 Provider 라는 컴포넌트와 아까 작성한 파일을 import 하고

밑에 <Provider store={import해온거}> 이걸로 <App/> 을 감싸면 된다.

그럼 이제 <App>과 그 모든 자식컴포넌트들은 store.js에 있던 state를 맘대로 꺼내쓸 수 있다.

 

이제 사용해보자 ! 


✔ createSlice

createSlice({
    
})

createSlice는 useState와 비슷한 역할을 한다.

 

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

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

let stock = createSlice({
    name : 'stock',
    initialState : [10,11,12]
})

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

해당 코드처럼 user라는 createSlice를 만들고 내부에 내용을 작성하고,

reducer:{ }안에서 불러오고자 하는 createSlice를 작명하여 넣어주면 끝.

 

그리고

let data = useSelector((state) => {return state})

console.log(data.user) //'kim'
console.log(data.stock) //[10,11,12]

불러오고자 하는 js 파일에서 해당 코드를 작성해주면 store.js 파일에서 가지고와서 출력하면 된다.

 

조금 간단하게 불러오는 방법도 있다.

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

console.log(data.user) //'kim'
console.log(data.stock) //[10,11,12]

해당 코드처럼 불러와도 동일한 결과를 출력한다 ! 

 

👍 Redux가 참 편하고 좋지만 컴포넌트간 공유가 필요없으면 해당 js파일에 useState() 쓰는게 나음


❗ Redux의 state 변경하는 법

// -- 기존 --
let user = createSlice({
    name : 'user',
    initialState : 'kim',
    }
});

// -- 변경 --
let user = createSlice({
    name : 'user',
    initialState : 'kim',
    reducers : {
        changeInitialState(state){
            return state + 'jiwoo' //kimjiwoo
        },
        changeInitialState_2(){
            return 'ohjihyun' //ohjihyun
        },
    }
});

export let {changeInitialState, changeInitialState_2} = user.actions

해당 코드의 변경안 처럼 하면 된다.

reducers : { } 안에서 함수를 정의하고 함수의 매개변수에 state를 넣어주면 

기존 state값이 들어가게된다

그렇게 되면 위 코드의 state는 'kim'이다.

그리고 createSlice() 밑에 함수들을 export 해주면 된다.

 

다음으로 export한 데이터를 받는 방법에 대해서 알아보자.

import { useDispatch, useSelector } from 'react-redux';
import { changeInitialState, changeInitialState_2 } from "./../store.js" //불러올 함수 import

let dispatch = useDispatch()

dispatch(changeInitialState()) // 사용

 

✔ useDispatch()

리덕스 스토어에 변경된 상태값을 저장하기 위해서 사용.

 

다음으로 useDispatch를 이용하여 변경된 상태값을 출력해주면 된다

 

가벼운 예제로 이해를 도우겠다.

 

store.js

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

let user = createSlice({
    name : 'user',
    initialState : 'kim',
    reducers : {
        changeInitialState(state){   
            return state + 'jiwoo'
        }
    }
});

export let {changeInitialState} = user.actions

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

app.js

import { useDispatch, useSelector } from 'react-redux';
import { changeInitialState } from "./../store.js"

funtion App(){
    let user = useSelector((state) => { return state.user }) //'kim'
    let dispatch = useDispatch()
    
    return (
        <div>
            {user}의 장바구니
            <button onClick={() => {dispatch(changeInitialState())}}>버튼</button>
        </div>
    )
}

예제 코드를 간단히 살펴보자.

 

해당 코드를 보면 바로 이해할 수 있을것이다.

user는 store.js에서 받아온 'kim'이 담겨있고 state에 'jiwoo' 문자열을 붙혀주는 함수가 있고

그 함수를 export한 뒤 app.js에서 export한 함수를 import하고 

버튼 클릭 시 changeInitialState() 함수를 통해 변경되는 상태값을 저장해주고

'kim의 장바구니'가 'kimjiwoo의 장바구니'로 변경된다

 

👍 수정 과정은 다음과 같다.

1. store.js 안에 state 수정해주는 함수부터 만든다. 

2. 함수를 export 한다.

3. 원하는 곳에서 import 해서 사용한다.

4. useDispatch()를 이용하여 변경된 상태값을 저장한다.


❗ state가 object/array일 경우 변경하는 법

 

1. 직접 수정

let user = createSlice({
    name : 'user',
    initialState : {name : 'kim', age : 20},
    reducers : {
        changeInitialState(state){
            state.name = 'park' // 직접적으로 수정
        }
    }
});

reducers안에 함수를 정의한 후 object 형식의 state값을 매개변수로 받아

state.("key") = "변경하고자 하는 값"을 통해 직접적으로 수정할 수 있다