Expo+Redux(+firebase)로 로그인 폼 ③ ~ 파일 정리 · Debugger ~
소개
Expo+Redux(+firebase)로 로그인 폼② ~Redux 도입~ 의 계속입니다.
이 기사에서는 Ducks 패턴을 인식하고 Redux의 각 부분을 파일로 나누고 ReactNativeDebugger를 사용할 수있게 될 때까지 다룹니다.
파일 분할 후 디렉토리 구성
root/
├ src/
├ App.tsx
├ store.ts
├ Styles.ts
├ components/
├ Counter.tsx
├ containers/
├ Counter.ts
├ modules/
├ index.ts
├ CounterModule.ts
├ node_modules/
├ package.json
파일 분할
거의, 마지막 기사 의 App.tsx 를 분할했을 뿐입니다.
앱
src/App.tsximport React from 'react';
import { Provider } from 'react-redux'
import store from './store'
import CounterContainer from './containers/Counter'
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
스토어
src/store.tsimport { createStore, combineReducers } from 'redux'
import { counterModule } from './modules'
const store = createStore(
combineReducers({ count: counterModule.counter })
)
export default store
스타일
src/Styles.tsimport { StyleSheet } from 'react-native'
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
})
export default styles
이것은 없어도 좋지만 스타일을 붙이지 않으면 화면 왼쪽 상단에 요소가 모여 버리기 어렵습니다.
Component
src/components/Counter.tsximport React from 'react'
import { View, Text, Button } from 'react-native'
import styles from '../Styles'
const Counter = ({ count, increment, decrement }) => (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={increment}
/>
<Button
title='DECREMENT'
onPress={decrement}
/>
</View>
)
export default Counter
React의 Presentational Component입니다.
Button이 눌려졌을 때에 불리는 함수는 아래의 Container에 구현해 두고, props로 건네주도록(듯이) 하고 있습니다. 로직은 Component에는 쓰지 않는 편이 좋은 것 같습니다.
Container
src/containers/Counter.tsimport { connect } from 'react-redux'
import { counterModule } from '../modules'
import Counter from '../components/Counter'
const mapStateToProps = state => {
return ({
count: state.count
})
}
const mapDispatchToProps = dispatch => {
return ({
increment: () => dispatch(counterModule.increment()),
decrement: () => dispatch(counterModule.decrement())
})
}
const CounterContainer = connect(mapStateToProps, mapDispatchToProps)(Counter)
export default CounterContainer
mapStateToProps, mapDispatchToProps를 정의하고 connect를 사용하여 Component에 전달합니다.
이번에는 사용하지 않지만 복잡한 논리가 필요하다면 이것에 mergeProps를 추가하는 것이 좋습니다.
모듈
src/modules/index.tsimport CounterModule from './CounterModule'
export const counterModule = new CounterModule()
module을 정리하고 있습니다. 앞으로 모듈이 많아지면 여기에 추가하는 느낌입니다.
src/modules/CounterModule.tsexport default class CounterModule {
// reducer
counter(state, action) {
if (action.type === 'undefined') {
return null
}
switch(action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return null
}
}
// actionCreator
increment = () => {
return { type: 'INCREMENT' }
}
decrement = () => {
return { type: 'DECREMENT' }
}
}
actionType도 만드는 것이 좋습니다. 어쨌든 생략했습니다.
React Native Debugger
이대로는 redux가 제대로 움직이고 있는지 알기 어렵기 때문에, 디버거를 사용하고 싶습니다.
이 기사 을 참고로 했는데, 그대로 움직이지 않았기 때문에 조금 수정합니다.
스토어 수정
src/store.tsimport { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { counterModule } from './modules'
const composeEnhancer = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(
combineReducers({ count: counterModule.counter }),
composeEnhancer(applyMiddleware(thunk))
)
export default store
이렇게 미들웨어의 redux-thunk를 끼지 않으면 디버거가 연결되지 않는 것 같습니다 (나도 잘 모르는 웃음)
디버거 설치, 시작
설치
brew update && brew cask install react-native-debugger
시작
open "rndebugger://set-debugger-loc?host=localhost&port=19001"
처음에는 단일 따옴표 ( ')로 묶여 있었지만 왜 오류
The file /Users/atsushi/myProjects/react-navigation-redux/‘rndebugger:/set-debugger-loc?host=localhost does not exist.
[1]+ Exit 1 open ‘rndebugger://set-debugger-loc?host=localhost
~
가 나왔으므로, 더블 쿼테이션(")으로 둘러싸서 보면, 잘 되었습니다.
다음 번
다음 번에는 React Navigation을 사용하여 화면 전환을 구현할 것입니다.
드디어 로그인, 가입 화면을 만들어 가게 됩니다.
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼 ③ ~ 파일 정리 · Debugger ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/AtsushiNi/items/13fc1f94674d9614e43f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
root/
├ src/
├ App.tsx
├ store.ts
├ Styles.ts
├ components/
├ Counter.tsx
├ containers/
├ Counter.ts
├ modules/
├ index.ts
├ CounterModule.ts
├ node_modules/
├ package.json
파일 분할
거의, 마지막 기사 의 App.tsx 를 분할했을 뿐입니다.
앱
src/App.tsximport React from 'react';
import { Provider } from 'react-redux'
import store from './store'
import CounterContainer from './containers/Counter'
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
스토어
src/store.tsimport { createStore, combineReducers } from 'redux'
import { counterModule } from './modules'
const store = createStore(
combineReducers({ count: counterModule.counter })
)
export default store
스타일
src/Styles.tsimport { StyleSheet } from 'react-native'
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
})
export default styles
이것은 없어도 좋지만 스타일을 붙이지 않으면 화면 왼쪽 상단에 요소가 모여 버리기 어렵습니다.
Component
src/components/Counter.tsximport React from 'react'
import { View, Text, Button } from 'react-native'
import styles from '../Styles'
const Counter = ({ count, increment, decrement }) => (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={increment}
/>
<Button
title='DECREMENT'
onPress={decrement}
/>
</View>
)
export default Counter
React의 Presentational Component입니다.
Button이 눌려졌을 때에 불리는 함수는 아래의 Container에 구현해 두고, props로 건네주도록(듯이) 하고 있습니다. 로직은 Component에는 쓰지 않는 편이 좋은 것 같습니다.
Container
src/containers/Counter.tsimport { connect } from 'react-redux'
import { counterModule } from '../modules'
import Counter from '../components/Counter'
const mapStateToProps = state => {
return ({
count: state.count
})
}
const mapDispatchToProps = dispatch => {
return ({
increment: () => dispatch(counterModule.increment()),
decrement: () => dispatch(counterModule.decrement())
})
}
const CounterContainer = connect(mapStateToProps, mapDispatchToProps)(Counter)
export default CounterContainer
mapStateToProps, mapDispatchToProps를 정의하고 connect를 사용하여 Component에 전달합니다.
이번에는 사용하지 않지만 복잡한 논리가 필요하다면 이것에 mergeProps를 추가하는 것이 좋습니다.
모듈
src/modules/index.tsimport CounterModule from './CounterModule'
export const counterModule = new CounterModule()
module을 정리하고 있습니다. 앞으로 모듈이 많아지면 여기에 추가하는 느낌입니다.
src/modules/CounterModule.tsexport default class CounterModule {
// reducer
counter(state, action) {
if (action.type === 'undefined') {
return null
}
switch(action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return null
}
}
// actionCreator
increment = () => {
return { type: 'INCREMENT' }
}
decrement = () => {
return { type: 'DECREMENT' }
}
}
actionType도 만드는 것이 좋습니다. 어쨌든 생략했습니다.
React Native Debugger
이대로는 redux가 제대로 움직이고 있는지 알기 어렵기 때문에, 디버거를 사용하고 싶습니다.
이 기사 을 참고로 했는데, 그대로 움직이지 않았기 때문에 조금 수정합니다.
스토어 수정
src/store.tsimport { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { counterModule } from './modules'
const composeEnhancer = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(
combineReducers({ count: counterModule.counter }),
composeEnhancer(applyMiddleware(thunk))
)
export default store
이렇게 미들웨어의 redux-thunk를 끼지 않으면 디버거가 연결되지 않는 것 같습니다 (나도 잘 모르는 웃음)
디버거 설치, 시작
설치
brew update && brew cask install react-native-debugger
시작
open "rndebugger://set-debugger-loc?host=localhost&port=19001"
처음에는 단일 따옴표 ( ')로 묶여 있었지만 왜 오류
The file /Users/atsushi/myProjects/react-navigation-redux/‘rndebugger:/set-debugger-loc?host=localhost does not exist.
[1]+ Exit 1 open ‘rndebugger://set-debugger-loc?host=localhost
~
가 나왔으므로, 더블 쿼테이션(")으로 둘러싸서 보면, 잘 되었습니다.
다음 번
다음 번에는 React Navigation을 사용하여 화면 전환을 구현할 것입니다.
드디어 로그인, 가입 화면을 만들어 가게 됩니다.
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼 ③ ~ 파일 정리 · Debugger ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/AtsushiNi/items/13fc1f94674d9614e43f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import React from 'react';
import { Provider } from 'react-redux'
import store from './store'
import CounterContainer from './containers/Counter'
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
import { createStore, combineReducers } from 'redux'
import { counterModule } from './modules'
const store = createStore(
combineReducers({ count: counterModule.counter })
)
export default store
import { StyleSheet } from 'react-native'
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
})
export default styles
import React from 'react'
import { View, Text, Button } from 'react-native'
import styles from '../Styles'
const Counter = ({ count, increment, decrement }) => (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={increment}
/>
<Button
title='DECREMENT'
onPress={decrement}
/>
</View>
)
export default Counter
import { connect } from 'react-redux'
import { counterModule } from '../modules'
import Counter from '../components/Counter'
const mapStateToProps = state => {
return ({
count: state.count
})
}
const mapDispatchToProps = dispatch => {
return ({
increment: () => dispatch(counterModule.increment()),
decrement: () => dispatch(counterModule.decrement())
})
}
const CounterContainer = connect(mapStateToProps, mapDispatchToProps)(Counter)
export default CounterContainer
import CounterModule from './CounterModule'
export const counterModule = new CounterModule()
export default class CounterModule {
// reducer
counter(state, action) {
if (action.type === 'undefined') {
return null
}
switch(action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return null
}
}
// actionCreator
increment = () => {
return { type: 'INCREMENT' }
}
decrement = () => {
return { type: 'DECREMENT' }
}
}
이대로는 redux가 제대로 움직이고 있는지 알기 어렵기 때문에, 디버거를 사용하고 싶습니다.
이 기사 을 참고로 했는데, 그대로 움직이지 않았기 때문에 조금 수정합니다.
스토어 수정
src/store.ts
import { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import { counterModule } from './modules'
const composeEnhancer = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const store = createStore(
combineReducers({ count: counterModule.counter }),
composeEnhancer(applyMiddleware(thunk))
)
export default store
이렇게 미들웨어의 redux-thunk를 끼지 않으면 디버거가 연결되지 않는 것 같습니다 (나도 잘 모르는 웃음)
디버거 설치, 시작
설치
brew update && brew cask install react-native-debugger
시작
open "rndebugger://set-debugger-loc?host=localhost&port=19001"
처음에는 단일 따옴표 ( ')로 묶여 있었지만 왜 오류
The file /Users/atsushi/myProjects/react-navigation-redux/‘rndebugger:/set-debugger-loc?host=localhost does not exist.
[1]+ Exit 1 open ‘rndebugger://set-debugger-loc?host=localhost
~
가 나왔으므로, 더블 쿼테이션(")으로 둘러싸서 보면, 잘 되었습니다.
다음 번
다음 번에는 React Navigation을 사용하여 화면 전환을 구현할 것입니다.
드디어 로그인, 가입 화면을 만들어 가게 됩니다.
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼 ③ ~ 파일 정리 · Debugger ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/AtsushiNi/items/13fc1f94674d9614e43f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼 ③ ~ 파일 정리 · Debugger ~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/AtsushiNi/items/13fc1f94674d9614e43f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)