기본적으로 Redux 사용을 익히기 위해 서버 없이 react로만 counter를 만들어보자
일단 react를 시작하기 전에 node가 설치되어 있어야 한다
설치했으면 react project를 생성해보자
npx creact-react-app react-project
npm install react-router-dom --save
npm install react-redux --save
npm install redux --save
npm install antd --save
npm install styled-components --save
redux와 라우팅 관련, 템플릿, css 라이브러리 설치
@antd 사용이 안 될 경우
프로젝트/src/App.js 파일로 가면 아래처럼 css 파일을 import하고 있는 것을 볼 수 있다
import './App.css';
프로젝트/src/App.css 파일에 아래 코드를 추가한다
@import '~antd/dist/antd.css';
실행 명령어
npm run start
함수형 컴포넌트, hook을 사용하기 때문에
mapPropsToState, mapDispatchToState 대신에
useSelector, useDispatch를 사용할 것이다
① View 페이지 생성
src/components/views/LandingPage/LandingPage.js
import React from 'react';
import { PlusCircleOutlined, MinusCircleOutlined } from '@ant-design/icons';
import styled from 'styled-components';
const LandingTemplate = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 100px;
button {
width: 200px;
height: 50px;
margin-right: 10px;
}
`;
function LandingPage() {
return (
<LandingTemplate>
<div>
<h1></h1>
</div>
<button><PlusCircleOutlined />1</button>
<button><MinusCircleOutlined />1</button>
</LandingTemplate>
)
}
export default LandingPage;
② Router 세팅
src/App.js
import logo from './logo.svg';
import './App.css';
import { BrowserRouter, Route, Switch } from "react-router-dom";
import LandingPage from "./components/views/LandingPage/LandingPage";
function App() {
return (
<BrowserRouter>
<Switch>
<Route exact={true} path="/" component={LandingPage} />
</Switch>
</BrowserRouter>
);
}
export default App;
③ Action 세팅
⑴ src/actions/types.js
export const INCREMENT = 'counter/increment';
export const DECREMENT = 'counter/decrement';
⑵ src/actions/counter.js
import { INCREMENT, DECREMENT } from './types';
export const increment = () => ({
type: INCREMENT
})
export const decrement = () => ({
type: DECREMENT
})
export const initialState = {
number: 0
}
Chrome에서 Redux 스토어를 확인해 보면 counter에 { number: 0 }로 initialState가 들어가 있다
④ Reducer 세팅
⑴ src/reducers/counter.js
import { INCREMENT, DECREMENT } from '../actions/types';
import { initialState } from '../actions/counter';
export default function(state=initialState, action) {
switch(action.type) {
case INCREMENT:
return {...state, number: state.number + 1}
case DECREMENT:
return {...state, number: state.number - 1}
default:
return state;
}
}
⑵ src/reducers/index.js
import { combineReducers } from 'redux';
import counter from './counter';
const rootReducer = combineReducers({
counter, // ⑴
});
export default rootReducer;
⑴ Redux Store에 저장되는 이름
⑤ Store 세팅
src/index.js
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './reducers';
const devTools =
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__();
const store = createStore(rootReducer, devTools);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Store 세팅, Redux 크롬 확장 프로그램 다운은 아래 링크에서 자세히 확인 가능
developer0809.tistory.com/17?category=902243
⑥ View 수정
View에서 Action을 dispatch해서 state 변경하기
components/views/LandingPage/LandingPage.js
import React from 'react';
import { PlusCircleOutlined, MinusCircleOutlined } from '@ant-design/icons';
import styled from 'styled-components';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from '../../../actions/counter';
const LandingTemplate = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 100px;
h1 {
}
button {
width: 200px;
height: 50px;
margin-right: 10px;
}
`;
function LandingPage() {
const num = useSelector(state => state.counter.number) // ⑴
const dispatch = useDispatch();
const onIncrease = () => {
dispatch(increment())
}
const onDecrease = () => {
dispatch(decrement())
}
return (
<LandingTemplate>
<div>
<h1>{num}</h1>
</div>
<button onClick={onIncrease}><PlusCircleOutlined />1</button>
<button onClick={onDecrease}><MinusCircleOutlined />1</button>
</LandingTemplate>
)
}
export default LandingPage;
⑴ reducers/index.js에서 combine한 reducer명을 기준으로 가져온다
counter 완성
@ Flow 정리
action: 중복 없는 action 정의
reducer: state에 데이터 set, state 변경
➊ View
action을 import해서 useDispatch()를 이용해서 dispatch
useSelector()를 이용해서 state 값을 가져옴
ex)
const num = useSelector(state => state.counter.number);
const dispatch = useDispatch();
dispatch(increment());
➋ Action
중복이 없는 액션 타입 리턴
➌ Reducer
액션명과 동일한 reducer를 찾아 매칭
state에 데이터 set, state 변경
'React&React-Native > React' 카테고리의 다른 글
[#. React] react-paypal-express-checkout를 이용해서 React 웹에 Paypal 결제 연동하기 (0) | 2021.01.18 |
---|---|
[#. React] npx create-react-app CRA 실패, 에러 해결 (0) | 2020.12.29 |
[#. React] Functional Component 함수형에서 사용할 수 있게 된 React Hooks 정리하기 (0) | 2020.12.16 |
[#. React] import 중괄호 {}를 쓰는 이유 (0) | 2020.11.12 |
[#React] React 프로젝트에 Redux 사용하기(초기 설정) (0) | 2020.07.31 |