티스토리 뷰
1) 상태관리 흐름
(1) 리덕스 Store를 Component에 연결한다.
(2) Component에서 상태 변화가 필요할 때 Action을 부른다.
(3) Reducer를 통해서 새로운 상태 값을 만들고
(4) 새 상태값을 Store에 저장한다.
(5) Component는 새로운 상태값을 받아온다.(props를 통해 받아오니까 다시 랜더링된다.)
2) Redux
리덕스는 상태관리 라이브러리이다. (전역 상태관리를 편하게 할 수 있다.)
(1) State
리덕스에서는 저장하고 있는 상태값("데이터"라고 생각해도된다.)를 state라고 부른다.
딕셔너리 형태({key}: value) 형태로 보관한다.
(2) Action
상태에 변화가 필요할 때(= 가지고 있는 데이터를 변경할 때) 발생하는 것.
// 액션은 객체이다. 이런 형태로 쓰인다. type은 이름같은 것으로 임의의 문자열을 넣는다.
{type: 'CHANGE_STATE', data: {...}}
(3)ActionCreator
액션 생성 함수라고도 부른다. 액션을 만들기 위해 사용한다.
//이름 그대로 함수이다.
const changeState = (new_data) => {
// 액션을 리턴한다. (액션 생성 함수)
return {
type: 'CHANGE_STATE',
data: new_data
}
}
(4) Reducer
리덕스에 저장된 상태(=데이터)를 변경하는 함수이다.
→ 액션 생성 함수를 부르고
→ 액션을 만들면
→ 리듀서가 현재 상태(=데이터)와 액션 객체를 받아서
→ 새로운 데이터를 만들고
→ 리턴해준다.
// 기본 상태값을 임의로 정해준다.
const initialState = {
name: 'youjung'
}
function reducer(state = initialState, action) {
switch(action.type){
// action의 타입마다 케이스문을 걸어주면,
// 액션에 따라서 새로운 값을 돌려준다.
case CHANGE_STATE:
return {name: 'youjung1'};
default:
return false;
}
}
(5) Store
프로젝트에 리덕스를 적용하기 위해 만드는 것이다.
스토어에는 리듀서, 현재 애플리케이션 상태, 리덕스에서 값을 가져오고 액션을 호출하기 위한 몇 가지 내장 함수가 포함되어 있다. 생김새는 딕셔너리 혹은 json처럼 생겼다.
(6) dispatch
디스패치는 스토어의 내장함수로 액션을 발생 시키는 역할을 한다.
// 실제로는 이것보다 코드가 길지만,
// 간단히 표현하자면 이런 식으로 우리가 발생시키고자 하는 액션을 파라미터로 넘겨서 사용한다.
dispatch(action);
3) 리덕스가 필요하지 않은 경우
1.페이지 간 공유할 데이터가 없는 경우
2.페이지 이동 시 리패칭이 잦게 일어날 경우
3.비즈니스 로직이 획일화되기 어려울 경우
Redux Toolkit
리덕스툴킷은 리덕스를 편히 쓰기 위해 리덕스 팀에서 만든 패키지이다.
리덕스를 사용하는데 유용한 패키지 도구 모음.
툴 킷을 쓰게 되면 액션타입, 액션 생성함수, 리듀서, 기초값을 하나 번에 묶어서 사용할 수 있다.
→ 보일러 플레이트가 많이 줄어든다.
4) store 만들기
(1) import 할 것부터 다 하기
import { createStore, combineReducers, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import { createBrowserHistory } from "history";
import { connectRouter } from "connected-react-router";
import User from "./modules/user";
(2) root reducer 만들기
const rootReducer = combineReducers({
user: User,
});
(3) 미들웨어 준비하기
const middlewares = [thunk];
// 지금이 어느 환경인지 알려준다. (개발환경, 프로덕션(배포)환경 ...)
const env = process.env.NODE_ENV;
// 개발환경에서는 로거라는 걸 하나만 더 써볼 것이다.
if (env === "development") {
const { logger } = require("redux-logger");
middlewares.push(logger);
}
(4) 크롬 확장 프로그램 redux devTools 사용 설정하기
(5) 미들웨어 묶기
const enhancer = composeEnhancers(
applyMiddleware(...middlewares)
);
(6) 미들웨어와 루트 리듀서를 엮어서 스토어를 만든다.
let store = (initialStore) => createStore(rootReducer, enhancer);
export default store();
5) slice 만들기
(1) import하기
import { createAction, handleActions } from "redux-actions";
import { produce } from "immer";
(2) 필요한 액션 만들기
const SET_POST = "SET_POST";
const ADD_POST = "ADD_POST";
const setPost = createAction(SET_POST, (post_list) => ({post_list}));
const addPost = createAction(ADD_POST, (post) => ({post}));
(3) initialState 만들기
const initialState = {
list: [],
}
// 게시글 하나에는 어떤 정보가 있어야 하는 지
const initialPost = {
user_info: {
id: 0,
user_name: "mean0",
user_profile: "https://mean0images.s3.ap-northeast-2.amazonaws.com/4.jpeg",
},
image_url: "https://mean0images.s3.ap-northeast-2.amazonaws.com/4.jpeg",
contents: "고양이네요!",
comment_cnt: 10,
insert_dt: "2021-02-27 10:00:00",
};
(4) 리듀서 작성하기
// reducer
export default handleActions(
{
[SET_POST]: (state, action) => produce(state, (draft) => {
}),
[ADD_POST]: (state, action) => produce(state, (draft) => {
})
},
initialState
);
(5) export 하기
// action creator export
const actionCreators = {
setPost,
addPost,
};
export { actionCreators };
6) redux hook - 데이터 구독하기
// pages/PostList.js
...
import {useSelector} from "react-redux";
...
const PostList = (props) => {
const post_list = useSelector((state) => state.post.list);
...
7) redux hook - 데이터 수정하기
...
import {actionCreators as userActions} from "../redux/modules/user";
import { useDispatch } from "react-redux";
const Login = (props) => {
const dispatch = useDispatch();
const [id, setId] = React.useState('');
const [pwd, setPwd] = React.useState('');
const changeId = (e) => {
setId(e.target.value);
}
const changePwd = (e) => {
setPwd(e.target.value);
}
const login = () => {
dispatch(userActions.login({user_name: "perl"}));
}
return (
<React.Fragment>
<Grid padding={16}>
<Text type="heading">로그인 페이지</Text>
</Grid>
<Grid padding={16}>
<Input value={id} onChange={changeId} placeholder="아이디를 입력하세요."/>
<Input value={pwd} onChange={changePwd} type="password" placeholder="비밀번호를 입력하세요."/>
</Grid>
<Button __click={() => {login();}}>로그인</Button>
</React.Fragment>
)
}
export default Login;
'프론트엔드 > React' 카테고리의 다른 글
네트워크 요청 1 - XMLHTTPRequest (0) | 2022.06.06 |
---|---|
Mock API (0) | 2022.06.05 |
ContextAPI() (0) | 2022.06.04 |
상태관리 (0) | 2022.06.04 |
async, await (0) | 2022.06.04 |
- Total
- Today
- Yesterday
- redux middleware
- 얕은복사
- 느슨한 타입(loosely typed)
- 비교 연산자
- findindex
- redux thunk
- 참조형 데이터
- find
- redux
- EVERY
- undefined
- 동적(dynamic) 언어
- map
- 기본형 데이터
- 불변 객체
- redux-thunk
- 타입변환
- foreach
- null
- filter
- some
- redux-middleware
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |