* 아래의 글은 Do Your Best 프롤로그를 먼저 읽으신 후 읽으시기를 권장합니다.
2020.07.10
오늘의 목표
- React Hooks와 React-Redux를 사용한 카운터 만들기
- React Hooks에서 Redux 연결해서 사용하기
동기
- class형 컴포넌트가 아닌 함수형 컴포넌트로 개발하고 싶어서
- 개발 시간 단축 및 효율성을 높이고싶기 때문에
React Hooks의 기본정보를 알기 위해서는 2020.07.08.과 2020.07.09. 게시글을 보시면 됩니다 😀
이 글은 Redux와 React-Redux에 대한 기본 지식이 있어야 합니다 😥
저는 https://velopert.com/1266 이 글을 제일 추천합니다! 저도 이 글을 보고 공부했는데 정말 이해하기 쉽게 되어있습니다. 단... 저 글의 코드는 전부 class형 component로 작성되어있습니다 ㅠㅠ
저 글을 읽고 다시 저의 글로 와서 React Hooks로 모두 코드를 리팩토링 하는걸 추천드립니다🥰
Counter 앱 만드는 전체코드는 제 깃헙 simplecounter(https://github.com/Bigstar1108/Do_Your_Best/tree/master/simple-counter)에서 자세히 볼 수 있습니다 😋
아래의 글에서는 simplecounter를 만들면서 배운 중요한 지식들을 공유하겠습니다 🙄
저는 simplecounter를 만들면서 React Hooks에서 Redux에 연결하는 방법이 class component에서 Redux와 연결하는 방법과 다르다는 것에 놀랐고, 코드를 완성하고나서 훨씬 효율적이라는 것에 또 놀랐습니다!
제가 놀란 코드를 같이 보면서 공부해볼까요~?
일단 먼저 action과 reducer를 작성해야겠죠? action 먼저 작성해봅시다.
export const INCREMENT = 'INCREMENT';
export const DECREMENT = "DECREMENT";
export const SET_DIFF = 'SET_DIFF';
//카운터를 증가하는 함수
export function increment(){
return{
type : INCREMENT
};
}
//카운터를 감소시키는 함수
export function decrement(){
return{
type : DECREMENT
};
}
//사용자가 정한 option값을 적용하는 함수
export function setDiff(value){
return{
type : SET_DIFF,
diff : value
}
}
simplecounter의 액션은 다음과 같은 모습입니다!
여기는 딱히 어려운 부분이 없습니다. 각 함수의 타입을 선언하고, 함수마다 맞는 액션타입을 선언해주고 쉽죠...? ㅎㅎ
이제 reducer코드를 작성해봅시다.
import { INCREMENT, DECREMENT, SET_DIFF } from '../actions';
import { combineReducers } from 'redux';
const counterInitialState = {
value : 0,
diff : 1
};
const counter = (state = counterInitialState, action) => {
switch(action.type){
case INCREMENT:
return Object.assign({}, state, {
value : state.value + state.diff
});
case DECREMENT:
return Object.assign({}, state, {
value : state.value - state.diff
});
case SET_DIFF:
return Object.assign({}, state, {
diff : action.diff
});
default:
return state;
}
};
const extra = (state = { value : 'this_is_extra_reducer' }, action) => {
switch(action.type){
default:
return state;
}
}
const counterApp = combineReducers({
counter,
extra
});
export default counterApp;
extra는 combineReducers 사용을 연습하기 위해 만든 함수이므로 무시하셔도 됩니다 ㅎㅎ
reducer에서는 counterInitialState에 value와 diff를 선언해줍니다.
value는 실제로 view에 리턴되는 카운터 value 값이고, diff는 사용자가 정한 option 값입니다.
INCREMENT에서는 실제로 value에 diff를 더해 카운터 증가를 다루고,
DECREMENT에서는 value에 diff를 빼 카운터 감소를 다루고,
SET_DIFF에서는 사용자에게 입력받은 diff값을 state의 diff에 저장합니다.
이렇게 보니 reducer코드도 간단하군요!
이제 제일 중요한 React Hooks에서 Redux를 적용시키는 코드를 작성해봅시다!
저는 제일 상위 파일인 App.js에서
- value값을 보여주는 Counter.js
- 증가, 감소 버튼이 있는 Button.js
- 사용자가 option값을 입력할 수 있는 Option.js
위의 세 개의 component로 나누어 코드를 작성했습니다.
제일 먼저 value값을 보여주는 Counter.js 코드를 작성해봅시다.
import React from 'react';
import { useSelector } from 'react-redux';
const Counter = () => {
const value = useSelector((store) => store.counter.value);
return(
<h1>VALUE : {value}</h1>
);
}
export default Counter;
와우... 코드만 봐도 마음의 편안과 안정이 오죠...😱 정말 React Hooks는 신이 주신 선물입니다...
React Hooks에서는 react-redux에서 지원해주는 useSelector만 사용하면 끝납니다.
코드를 분석해보자면...
useSelector((store) => store.원하는리듀서이름.원하는값); 인 것 같습니다.
저는 reducer에서 counter를 제어하는 reducer이름을 counter로 지정해주었고, 저희가 들고와야하는 state값의 이름은 value이기 때문에 store.counter.value로 코드를 작성했습니다.
이제 얼마나 증가, 감소 할 건지 diff 값을 정하는 Option.js 코드를 작성해봅시다.
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { setDiff } from '../actions/index';
const useInput = (initialValue) => {
const [value, setValue] = useState(initialValue);
const dispatch = useDispatch();
const onChange = event => {
const {
target : {value}
} = event;
if(!value){
return;
}
setValue(value);
if(value === ''){
setValue(0);
}
dispatch(setDiff(parseInt(value)));
}
return {value, onChange};
}
const Option = () => {
const { value, onChange } = useInput(1);
return(
<div>
<input type = "text" onChange = {onChange} placeholder = "input option" />
</div>
);
}
export default Option;
제 생각엔 Option.js코드가 제일 복잡한 것 같네요. 그래도 열심히 공부해봅시다!
여기서는 useInput 함수만 이해하면 끝입니다!
useSelector와 같이 react-redux에서 useDispatch를 불러옵니다.
const [ value, setValue ] = useState(initialValue); 이 코드는 저의 블로그 글을 읽어보셨으면 이해하셨겠죠?
input의 value와 value값을 정해줄 setValue입니다. 그리고 초기 값을 적용시켜줍니다.
const dispatch = useDispatch(); dispatch를 사용해 이제 action에 있는 함수를 실행시킬거에요.
그 아래의 코드 중 중요한 것은 dispatch(setDiff(parseInt(value))); 이 코드인 것 같네요.
이 코드를 차근차근 알아봅시다! 겁나 복잡해보여도 사실 알고나면 별거 아닌 코드에요 ㅎㅎ
import { setDiff } from '../actions/index'; - 자기가 사용할 action 함수를 불러옵니다.
dispatch(사용할 함수()); 이렇게 사용합니다.
저는 input값으로 받은 값을 int 형으로 diff에 저장해야하기 때문에 위와 같이 코드를 작성했습니다.
이제 Option도 끝났습니다. 남은건 Button.js밖에 없죠 ㅎ 후딱 끝내봅시다!
import React from 'react';
import { increment, decrement } from '../actions/index';
import { useDispatch } from 'react-redux';
const Button = () => {
const dispatch = useDispatch();
return(
<div>
<button onClick = {() => dispatch(increment())}>+</button>
<button onClick = {() => dispatch(decrement())}>-</button>
</div>
);
}
export default Button;
Option.js를 먼저 보고 이 코드를 보니 왜 저렇게 코드를 작성했는지 이해가 되시죠?
똑같이 increment와 decrement를 action에서 불러온 후, dispatch를 사용해 onClick시 적합한 함수를 실행했습니다.
정말 간단하죠? class형 component였으면 적어도 10줄 이상은 추가되었을텐데... React Hooks 정말 좋습니다.
자 이제 마무리를 합시다! 마지막 App.js입니다!
import React from 'react';
import Counter from './components/Counter';
import Button from './components/Button';
import Option from './components/Option';
function App(){
return(
<div style = {{textAlign : "center"}}>
<Counter />
<Button />
<Option />
</div>
);
}
export default App;
정말 별 거 없습니다! 정말 Counter와 Button Option 순서대로 불러오면 되기 때문이죠!
이제 결과물을 확인해 볼까요?
저의 결과물과 똑같아서 (https://velopert.com/1266) 블로그의 글에서 이미지를 복사해 첨부하였습니다!
React Hooks와 react-redux를 사용하니 정말 간편하고, 간단하게 카운터를 구현할 수 있죠?
이렇게 하나하나 해나갈때마다 뿌듯하면서 React-Hooks의 대단함을 한번 더 느낍니다!
이 글을 읽으시는 모든 분들 저와 함께 하나하나씩 더 공부해봅시다! 감사합니다 😊
2020.07.10. 회고
오늘의 목표를 이루었는가?
React Hooks와 React-Redux를 사용한 카운터 만들기React Hooks에서 Redux 연결해서 사용하기
2020.07.10. 하루를 지낸 소감
처음으로 오늘의 목표를 다 이룬 하루였다... 정말 힘들었고 지쳤지만 막상 블로그 글을 작성하면서 하루를 마무리하는데 오늘 하루를 보상받은 것처럼 개운하고, 기분이 좋다.
솔직히 말해서 블로그 글을 쓰는거에 강박이 생기는 느낌이다. 블로그 글 작성을 끝낸다고 안하던 심자를하고, 오늘은 12시를 넘겨서 잤다. 이런날이 반복될거라는 것을 잘 안다. 이것은 안하려고 하는 변명이 아니다. 강박이 생길만큼 부지런하게 하지 않은 나의 잘못이라고 생각한다. 그래서 나는 하루의 시간을 정확히 나누어야겠다.
'학습 시간', '쉬는 시간', '블로그 작성시간', '밥시간 ㅎㅎ'을 정확히 나누어야겠다. 공부하다가 블로그 글쓰다가 왔다갔다 하니까 정확도도 떨어지고 머리에 덜 들어오는 느낌이다. 공부를 하면서 중요한 점들을 마킹해놓고, 블로그를 쓰면서 복습하는 느낌으로 한번 더 공부하는 형식으로 블로그 글을 작성해야겠다.
너무 힘들기도 하고 너무 기분좋기도하다. 하루하루 늘어나는 방문자 수들과 방문수를 늘어가면서 이게 관종인가 싶기도 하고 그래도 기분 좋다. 그냥 내가 쓴 글이 읽었다는 거에서 끝나는 것이 아니라 정말 이 글을 읽고 도움이 되는 사람들이 있었으면 좋겠다. 정말 도움이 된다면 댓글이라도 남겨주셨으면 좋겠다. 열심히 하면 언젠가는 남겨주시겠지.
내일도 모레도 열심히 하자. 변명 따위 없이 그냥 열심히 살자.
오늘은 하루를 지낸 소감이 겁나 길었다. 그냥 요약하자면 열심히 살자 인 것 같다.
이 글을 읽으시는 모든 분들이 자기가 하는거에 정말 목숨을 걸었다고 생각하고 열심히, 도전해보셨으면 좋겠다.
오늘 하루도 수고하셨어요. 내일도 좋은 하루가 되시길 바랍니다. 긴 글 읽어주셔서 감사합니다🥰😁
아래는 이 글을 쓰면서 도움을 받은 링크입니다.
저의 글보다 훨씬 더 좋은 영상과 자료들이 많으니 아래의 사이트도 한 번씩 들어가보시는 것을 추천드립니다!
리액트 Hooks 공식 문서 - https://ko.reactjs.org/docs/hooks-intro.html
React-Redux Hooks - https://levelup.gitconnected.com/react-redux-hooks-useselector-and-usedispatch-f7d8c7f75cdd
리액트의 Hooks 완벽 정복하기 - https://velog.io/@velopert/react-hooks
Redux: 예제를 통해 사용해보기 - https://velopert.com/1266
저의 깃헙 링크도 첨부하겠습니다. 공부하면서 작성한 코드가 있으니 들어오셔서 봐주시면 감사하겠습니다!
Bigstar1108 - https://github.com/Bigstar1108/Do_Your_Best
'Do Your Best' 카테고리의 다른 글
2020.07.12. (0) | 2020.07.12 |
---|---|
2020.07.11. (0) | 2020.07.11 |
2020.07.09. (0) | 2020.07.09 |
2020.07.08. (0) | 2020.07.08 |
Do Your Best 프롤로그 (0) | 2020.07.08 |