개발환경...
System:
OS: macOS 11.1
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 2.10 GB / 32.00 GB
Shell: 5.8 - /bin/zsh
Binaries:
Node: 17.3.1 - /usr/local/bin/node
Yarn: Not Found
npm: 8.3.1 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.11.2 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
Android SDK: Not Found
IDEs:
Android Studio: 4.2 AI-202.7660.26.42.7351085
Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild
Languages:
Java: 11.0.9.1 - /usr/bin/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.66.4 => 0.66.4
react-native-macos: Not Found
npmGlobalPackages:
*react-native*: Not Found
출처 :
https://redux.js.org/introduction/getting-started
Getting Started with Redux | Redux
Introduction > Getting Started: Resources to get started learning and using Redux
redux.js.org
1. Redux 설치하기
1
|
npm install redux
|
cs |
2. redux 폴더 생성
필자는 기본적으로 루트디렉토리에 src 폴더를 만들고 사용하는 모든 파일을 넣는다.
3. reducer 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/*user.tsx*/
const initialState = null
export const userReducer = (
state: WFSUser | null = initialState,
action: { type: any, payload?: any })
: WFSUser | null => {
switch (action.type) {
default:
break;
}
return state
}
|
cs |
유저의 기본적인 값들을 담을 userReducer를 만들어 줍니다.
리듀서는 두개의 값이 필수적입니다. state 와 action 입니다.
- state는 해당 리듀서가 반환하는 값의 타입을 지정합니다.
- action은 리듀서에서 어떤 작업을 할지 정해주는 역할을 합니다.
userReducer는 유저가 로그인 하면 WFSUser 클래스를, 그렇지 않으면 null를 반환합니다.
/**22.01.18
Error: The slice reducer for key "user" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.
undefined를 사용하면 안된답니다. 대신 null을 사용하라 합니다. 본문 내용은 수정하였습니다.
*/
*** state의 타입과 reducer의 return 타입은 동일해야합니다.***
reducer에 들어가는 뼈대를 만들었으니 이제 action 을 작성해봅시다.
4. action 작성
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
|
/*user.tsx*/
const initialState = null
export const updateUserInfo = (newUserState: WFSUser) => {
return {
type: "UPDATE_USER_INFO",
payload: newUserState
}
}
export const initializeUserInfo = () => {
return {
type : "INITIALIZE_USER_INFO",
payload : null
}
}
export const userReducer = (
state: WFSUser | null = initialState,
action: { type: any, payload?: any })
: WFSUser | null => {
switch (action.type) {
case "UPDATE_USER_INFO":
return action.payload
case "INITIALIZE_USER_INFO":
return action.payload
default:
break;
}
return state
}
|
cs |
위와 똑같은듯 비슷하죠? 같은 파일내에 작성했기 때문입니다.
새로 생긴 updateUserInfo 와 initializeUserInfo가 바로 action 입니다.
action 함수를 호출하면 userReducer에서 action.type을 통해 state(user)를 수정합니다.
5. type 작성
reducer에서는 어떤 작업을 수행할 지를 action의 type을 통해서 구분합니다.
위 "action작성"의 코드를 참고하여
우선 action에서 상태를 변경할 때 사용되는 payload와 함께 type을 reducer에게 보냅니다.
그러면 reducer에서는 switch를 통해 type을 확인하고 payload를 사용하여 상태를 수정하여 저장합니다.
이 때, 같은 문자열이 두 번 쓰입니다. 때문에 일반적으로 이를 따로 분리합니다. 아래와 같이 말이죠
이는 리듀서와 액션이 담긴 user.tsx와 같은 redux/reducer/user 폴더 안에 위치합니다.
자 그러면 완성된 user.tsx와 user.type.tsx를 살펴볼까요
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
32
33
34
35
36
37
|
//user.tsx
import { WFSUser } from "../../../classes/User";
import { INITIALIZE_USER_INFO, UPDATE_USER_INFO } from "./user.type";
const initialState = null
export const updateUserInfo = (newUserState: WFSUser) => {
return {
type: UPDATE_USER_INFO,
payload: newUserState
}
}
export const initializeUserInfo = () => {
return {
type : INITIALIZE_USER_INFO,
payload : null
}
}
export const userReducer = (
state: WFSUser | null = initialState,
action: { type: any, payload?: any })
: WFSUser | null => {
switch (action.type) {
case UPDATE_USER_INFO:
return action.payload
case INITIALIZE_USER_INFO:
return action.payload
default:
break;
}
return state
}
//user.type.tsx
export const UPDATE_USER_INFO = "UPDATE_USER_INFO"
export const INITIALIZE_USER_INFO = "INITIALIZE_USER_INFO"
|
cs |
6. store 작성
src/redux 위치에 store.tsx 파일을 생성합니다.
1
2
3
4
5
6
7
8
9
10
11
|
import { combineReducers, createStore, Reducer, Store } from "redux";
import { userReducer } from "./reducer/user/user";
const rootReducer : Reducer = combineReducers({
user : userReducer,
//someState : someStateReducer
})
const store : Store = createStore(rootReducer);
export default store;
|
cs |
그리고 위와 같이 작성합니다. 쉽죠?
다른 reducer를 추가하려면 앞서 했던 reducer,action,type의 과정을 한 뒤에
주석처리한 someState : somStateReducer 와 같이 작성하시면 됩니다.
7. 사용법
이제 세팅은 모두 끝났습니다. 사용만 하면되죠.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import { Provider, useDispatch, useSelector } from 'react-redux'
import store from './src/redux/store';
import { updateUserInfo } from './src/redux/reducer/user/user';
const App = () => {
const reduxState = useSelector((state: { user: WFSUser | null }) => state);
const reduxDispatch = useDispatch();
const updateuUserRedux = () => {
reduxDispatch(updateUserInfo(new WFSUser("홍길동", "email@email.com", "email", false, "uid")))
}
return (
<Provider store={store}>
<View>
{/* <ThemeButton text="THEME_BUTTON" />
<ScrollView
contentInsetAdjustmentBehavior="automatic">
</ScrollView> */}
</View>
</Provider>
);
};
|
cs |
<Provider stort={store}></Provider> 태그로 root tag 를 감싸주세요.
그럼 이제 <Provider>의 Child에서는 모두 store 가 가진 상태들을 사용할 수 있습니다.
우선 호출 방법은 다음과 같습니다.
useSelector() 는 store의 상태가 변화 될때 마다 모든 state를 반환합니다.
이를 사용하시면 됩니다.
두번째로 상태 변경방법입니다.
useDispatch()를 reduxDispatch(변수명 자유롭게)로 선언해줍니다.
첫번째 매개변수로 앞서 정의한 action을 호출하여 상태를 변경할 수 있습니다.
8. 작동원리
Provider 태그를 사용하여 컴포넌트들을 감쌉니다.
useDispatch를 정의하고 첫번째 매개변수로 action을 호출합니다.
호출된 action이 type과 payload를 반환합니다.(action : {type:any,payload?:any})
이를 useDispatch가 모든 reducer에게 넘겨줍니다.
reducer안에 switch에서 type을 검출하여 동일한 case를 실행시킵니다.
state가 변경됩니다.
부족함이 많은 블로그 찾아주셔서 감사드립니다.
추가적으로 잘못된 부분이나 궁금한 내용은 댓글을 남겨주세요.
'JavaScript > React Native' 카테고리의 다른 글
[React-Native] XML to JSON (1) | 2022.02.10 |
---|---|
[React-Native] fetch [TypeError: Network request failed] 오류 (0) | 2022.02.09 |
안드로이드 폰트 스케일링 끄는 법(Disable FontScaling [React Native] (0) | 2021.07.30 |
[React-Native] 도움이 되는 사이트 (0) | 2021.05.10 |
[React-Native] error Could not find "Podfile.lock" (0) | 2021.05.10 |
댓글