일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 프론트엔드
- react localStorage
- 타입스크립트
- 브라우저
- 프리온보딩
- state
- localstorage
- Reducer
- Frontend
- 원티드
- JavaScript
- firebase
- 자바스크립트
- es6
- til
- v9
- 컴포넌트
- 비트 연산자
- 알고리즘
- Redux
- 리액트
- TypeScript
- 프로그래머스
- axios
- react
- Component
- 파이어베이스
- CORS
- array
- JS
- Today
- Total
도리쓰에러쓰
[React] Redux3 :: state와 reducer가 더 필요하다면? 본문
저번 게시물에 이어서 작성하겠습니다. (코드 참고)
1. redux를 통해 Alert창 닫기 기능 만들기
1️⃣ Cart..js에 alert 창을 하나 생성합니다.
* div class는 bootstrap에 정의되어 있는 것을 사용하였습니다.
<div className='alert alert-warning'>
<p>지금 구매하시면 신규할인 20%</p>
<button>닫기</button>
</div>
2️⃣ alert 창의 상태를 저장하는 state와 reducer를 만듭니다.
let alertState = true;
function reducer2(state = alertState, action) {
return state
}
3️⃣ createStore에 reducer2()를 추가합니다.
💡 이전엔 reducer가 한개만 있었기 때문에 아래 코드와 같이 작성하였습니다.
let store = createStore(reducer);
하지만 reducer 여러개일 때는 combineReducers()를 사용하여 아래 코드처럼 작성하면 됩니다.
let store = createStore(combineReducers({reducer, reducer2}));
4️⃣ reducer를 합치면 store에 담긴 데이터를 사용하는 부분도 변경해야 합니다.
💡 이전에 Cart.js에서 아래와 같은 코드를 작성한 적이 있었는데, 현재 reducer가 2개이기 때문에 에러가 납니다.
function store(state){
return {
state : state
}
}
- 실제로 console.log(state)를 찍어보면 아래 사진과 같은 결과가 출력됩니다.
- 에러가 나지 않으려면 아래 코드와 같이 작성하면 됩니다.
* state에는 상품 관련한 데이터가, alertState에는 alert창의 상태에 대한 데이터가 들어있습니다.
function store(state){
return {
state : state.reducer,
alertState : state.reducer2
}
}
5️⃣ state와 reducer를 통해 alert 창이 닫히도록 해보겠습니다.
1) index.js에 있는 reducer2()를 아래 코드와 같이 변경해줍니다.
function reducer2(state = alertState, action) {
if( action.type === 'alertClose' ) {
state = false;
return state;
} else {
return state;
}
}
- action type이 'alertClose'일 때 state값을 false로 변경합니다.
2) Cart.js에 삼항연산자를 통해 alertState가 true이면 alert창이 보이고, false이면 alert창이 닫히도록 하는 기능을 작성합니다.
{
props.alertState === true
? (<div className='alert alert-warning'>
<p>지금 구매하시면 신규할인 20%</p>
<button>닫기</button>
</div>)
: null
}
3) button onClick 이벤트리스너에 dispatch()를 작성하여 버튼을 클릭하면 데이터를 false로 데이터 수정 요청을합니다.
{
props.alertState === true
? (<div className='alert alert-warning'>
<p>지금 구매하시면 신규할인 20%</p>
<button onClick={ () => { props.dispatch({ type : 'alertClose' }) } }>닫기</button>
</div>)
: null
}
- 아래 사진과 같이 [닫기] 버튼을 클릭하면 alert창이 닫히는 것을 확인할 수 있습니다.
💡 주의
저는 문법을 보여드리기 위해 state와 reducer를 Component 하나에서만 보여드렸는데,
Component 하나에서만 쓰는건 굳이 redux에 저장할 필요가 없습니다. (useState() 사용)
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 { combineReducers, createStore } from 'redux';
let alertState = true;
function reducer2(state = alertState, action) {
if( action.type === 'alertClose' ) {
state = false;
return state;
} else {
return state;
}
}
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);
let store = createStore(combineReducers({reducer, reducer2}));
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>
{
props.alertState === true
? (<div className='alert alert-warning'>
<p>지금 구매하시면 신규할인 20%</p>
<button onClick={ () => { props.dispatch({ type : 'alertClose' }) } }>닫기</button>
</div>)
: null
}
</div>
)
}
function store(state){
return {
state : state.reducer,
alertState : state.reducer2
}
}
export default connect(store)(Cart)
// export default Cart;
* 이외의 코드는 이전 게시물에 작성된 코드와 일치합니다.
'코딩애플 (React) > 기초수업(코딩애플) - 3' 카테고리의 다른 글
[React] Redux5 :: useSelector, useDispatch (0) | 2022.02.01 |
---|---|
[React] Redux4 :: dispatch로 데이터 보내기 (0) | 2022.02.01 |
[React] Redux2 :: reducer / dispatch로 데이터 수정하기 (0) | 2022.01.26 |
[React] Redux1 :: props 대신 사용하기 (0) | 2022.01.26 |
[React] Tab 만들기와 리액트에서의 등장 애니메이션 (0) | 2022.01.24 |