도리쓰에러쓰

[React] Redux2 :: reducer / dispatch로 데이터 수정하기 본문

코딩애플 (React)/기초수업(코딩애플) - 3

[React] Redux2 :: reducer / dispatch로 데이터 수정하기

강도리 2022. 1. 26. 23:41

저번 게시물에 이어서 작성하겠습니다. (코드 참고)

 

[React] Redux1 :: props 대신 사용하기

저번 게시물에 이어서 작성하겠습니다. (코드 참고) [React] Tab 만들기와 리액트에서의 등장 애니메이션 저번 게시물에 이어서 작성하겠습니다. (코드 참고) [React] Component가 많을 땐 Context API 사용

dori-coding.tistory.com


1. reducer() 이용하여 수량 변경하기

🔔 Redux 쓰는 이유

: state 데이터 관리 용이합니다.

 

 

redux에선 state 데이터의 수정방법을 미리 정의하는데,

지금부터 reducer() 세팅 방법 두가지를 알아봅시다.


💡 reducer() 세팅 방법 - 1

- index.js에서 store 변수에 createStore(reducer)를 넣고, reducer()를 정의한 후 데이터를 넣습니다.

  * 현재 코드에선 데이터 초기값 그대로 return합니다.

let store = createStore(reducer);

function reducer(){
  return [
    { id : 0, name : 'white bag', quan : 2 }, 
    { id : 1, name : 'black bag', quan : 5 }, 
    { id : 2, name : 'red bag', quan : 0 }
  ]
}

 

 

💡 reducer() 세팅 방법 - 2

1️⃣ basicState 변수를 만들어 데이터를 넣고, reducer() 함수를 만들어 아래 코드와 같이 세팅합니다.

  그리고 store 변수에 createStore()에 reducer를 넣습니다.

let basicState = [
  { id : 0, name : 'white bag', quan : 2 }, 
  { id : 1, name : 'black bag', quan : 5 }, 
  { id : 2, name : 'red bag', quan : 0 }
];

function reducer(state = basicState, action){
  return state
}

let store = createStore(reducer);

- reducer()는 항상 수정된 state를 return해야합니다.

- state = 초기값

 * default parameter (ES6 문법) : 함수를 만들 때 실수 또는 의도적으로 파라미터 입력을 안했을 때 기본으로 가질 파라미터를 부여할 수 있습니다. 아래 예시를 보겠습니다.

function test(a = 10, b = 20) {
	console.log(a + b);
}
test(1);	//21

: a자리엔 1이라는 파라미터가 들어왔는데 b엔 아무것도 안들어왔으니 b에는 default parameter로 만들어둔 20이 할당됩니다. 그래서 콘솔창에 21이 출력됩니다.

 

 

2️⃣ reducer() 작성법에 따라 reducer() 안에 다음과 같이 작성합니다.

⭐ reducer() 작성법

function reducer(state = basicState, action){
  if(데이터수정조건) {
    return 수정된state
  } else {
    return state
  } 
}

 

- 다음과 같이 작성해주세요.

function reducer(state = basicState, action){
  if( action.type === '수량증가' ) {
    let copyArr = [...state];
    copyArr[0].quan++;
    return copyArr;
  } else if( action.type === '수량감소' ) {
    let copyArr = [...state];
    copyArr[0].quan--;
    return copyArr;
  } else {
    return state
  } 
}

 * action.type === '수량증가'와 action.type === '수량감소'는 추후에 설명하고, 일단 데이터 수정 조건이라는 것만 알아두세요.

 * copyArr : state를 복사한 배열을 copyArr 변수에 저장합니다.

 * 수량 증가를 위해 quan에 +1을 합니다.

 * 수정된 copyArr를 return합니다.

 

 

3️⃣ Cart.js에서 [+]버튼을 클릭하면 수량증가 되고, [-]버튼을 클릭하면 수량감소가 되는 이벤트리스너를 작성합니다.

<td>
    <button onClick={()=>{ props.dispatch({ type : '수량증가' }) }}>+</button>
    <button onClick={()=>{ props.dispatch({ type : '수량감소' }) }}>-</button>
</td>

- 데이터 수정요청할 땐 props.dispatch({ type : ??? }) 방식으로 작성합니다.

- type이 '수량증가'일 땐 reducer()에서 작성한 '수량증가' 조건과 일치하는 것을 실행하고, 

  type이 '수량감소'일 땐 reducer()에서 작성한 '수량감소' 조건과 일치하는 것을 실행합니다.

 

 

- 다음과 같이 [+] 버튼을 누르면 수량이 증가하고, [-] 버튼을 누르면 수량이 감소하는 것을 확인할 수 있습니다.

수량 증가할 때
수량 감소할 때


2. 전체 코드

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import { BrowserRouter } from 'react-router-dom';

import { Provider } from 'react-redux';
import { createStore } from 'redux';

let basicState = [
  { id : 0, name : 'white bag', quan : 2 }, 
  { id : 1, name : 'black bag', quan : 5 }, 
  { id : 2, name : 'red bag', quan : 0 }
];

function reducer(state = basicState, action){
  if( action.type === '수량증가' ) {
    let copyArr = [...state];
    console.log(copyArr);
    copyArr[0].quan++;
    return copyArr;
  } else if( action.type === '수량감소' ) {
    let copyArr = [...state];
    copyArr[0].quan--;
    return copyArr;
  } else {
    return state
  } 
}

let store = createStore(reducer);

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

 

Cart.js

import React from 'react';
import { Table } from 'react-bootstrap';
import { connect } from 'react-redux';

function Cart(props) {
    return(
        <div>
            <Table responsive>
                <thead>
                    <tr>
                        <th>#</th>
                        <th>상품명</th>
                        <th>수량</th>
                        <th>변경</th>
                    </tr>
                </thead>
                <tbody>
                    {
                        props.state.map((a, i)=>{
                            return(
                                <tr key={i}>
                                    <td>{ a.id }</td>
                                    <td>{ a.name }</td>
                                    <td>{ a.quan }</td>
                                    <td>
                                        <button onClick={()=>{ props.dispatch({ type : '수량증가' }) }}>+</button>
                                        <button onClick={()=>{ props.dispatch({ type : '수량감소' }) }}>-</button>
                                    </td>
                                </tr>
                            )
                        })
                    }
                </tbody>
            </Table>
        </div>
    )
}

function store(state){
    return {
        state : state
    }
}

export default connect(store)(Cart)
// export default Cart;

 

* 이외의 코드는 이전 게시물에 작성된 코드와 일치합니다.

 

 

Comments