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 만 확인하면 됨
그래서 프로젝트의 사이즈가 커질수록 이렇게 코드를 짜는 것이 좋다.
'웹 > 24-StudyWithPnP' 카테고리의 다른 글
[React+JS/리액트] 웹 스터디 10주차 (0) | 2024.07.11 |
---|---|
[React+JS/리액트] 웹 스터디 9주차 (0) | 2024.07.04 |
[React+JS/리액트] 웹 스터디 7주차 (0) | 2024.06.05 |
[React+JS/리액트] 웹 스터디 6주차 (2) | 2024.06.03 |
[React+JS/리액트] 웹 스터디 5주차 (0) | 2024.05.23 |