rhanziy

React - Redux toolkit 에서 state 변경하기(장바구니 기능) 본문

React

React - Redux toolkit 에서 state 변경하기(장바구니 기능)

rhanziy 2022. 12. 6. 15:30

저번 글에서 redux toolkit을 설치하고 store.js 파일에 공유할 state들을 모아놨다.

이제 useState처럼 state를 변경하는 방법.

좀 복잡하다 ㅋ

 

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

 

 

장바구니에 담긴 아이템 data가 들어있다.

중복된 아이템이 추가되면 수량을 올리거나, 장바구니 아이템을 추가/삭제하는 기능을 만들어

state를 변경하고 싶다면 reducers를 이용해 기능을 추가하면 된다.

 

let cart = createSlice({
    name : 'cart',
    initialState : 
        [
            {id : 0, name : 'White and Black', count : 2},
            {id : 2, name : 'Grey Yordan', count : 1}
        ] ,
    reducers:{
        upCount(state, action){
            let index = state.findIndex((a)=> a.id == action.payload);
            state[index].count++;
        },
        addCart(state, action){
            let newData = action.payload;
            let newCart = {
                id : newData.id,
                name : newData.title,
                count : 1
            }
            let index = state.findIndex((a)=> a.id == newData.id);

            if(index == -1){
                state.push(newCart);
            } else {
                state[index].count++;
            }
        },
        delCart(state, action){
            let index = state.findIndex((a)=> a.id == action.payload);
            state.splice(index, 1);
        }
    }
})

 

뿅. reducers : { 함수, 함수, 함수  } 형식.

각 함수에는 state와 action 파라미터를 사용할 수 있는데 state는 기존 데이터고

action은 화면단과 상호작용으로 받은 데이터임.

action.payload 로 데이터에 접근할 수 있다.

=> 이부분은 아래 Cart.js 코드에서 확인

 

 

기능을 추가했으면 export를 해주자.

작명한 createSlice 변수에 .actions를 붙여주면 됨.

export let { upCount, addCart, delCart } = cart.actions;

export default configureStore({
    reducer:{
        cart : cart.reducer
    }

})

 

 

export까지 했다면, 구현할 Cart.js 컴포넌트에 가서 작명한 함수명으로 import.

그리고 useDispatch()를 import 해준다.

import { useSelector, useDispatch } from 'react-redux';
import { upCount, delCart } from '../store/store';


function Cart() {

    let state = useSelector((state) =>  state )
    let dispatch = useDispatch()  // store.js로 요청보내주는 함수
    
	return(
    	//생략
    )
}

 

 return (
        <div>
            <p>{state.user.name}{state.user.age}의 장바구니</p>
            <Table>
                <thead>
                    <tr>
                        <th>#</th>
                        <th>상품명</th>
                        <th>수량</th>
                        <th>변경하기</th>
                        <th>삭제</th>
                    </tr>
                </thead>
                <tbody>
                    { 
                        state.cart.map((a, i) =>
                            <tr key={i}>
                                <td>{i+1}</td>
                                <td>{a.name}</td>
                                <td>{a.count}</td>
                                <td>
                                    <button onClick={()=>{
                                        dispatch(upCount(a.id));
                                    }}> + </button>
                                </td>
                                <td>
                                    <button onClick={()=>{
                                        dispatch(delCart(a.id));
                                    }}> - </button>
                                </td>
                            </tr>
                        )
                    }
                </tbody>
            </Table>
        </div>
    )

 

사용은 이런식으로 하면됨.

버튼을 누르면 수량이 오르게? dispatch(upCount(a.id))

a.id는 upCount 의 action 파라미터로 보내는 값. action.payload로 접근이 가능할 것이다.

 

 

props전송을 쉽게하려고 리덕스툴킷 라이브러리를 설치하긴 했지만

export, action, dispatch 등등 복잡하게 느껴진다.

그래도 페이지가 많거나 컴포턴트 구성이 복잡한 경우엔 훨씬 유용하다고하니....

개념을 대충 배워놓으면 나중에 꼭 유용하게 쓸 것....

 

Comments