Expo+Redux(+firebase)로 로그인 폼② ~Redux 도입~
소개
Expo+Redux(+firebase)로 로그인 폼 ① ~ 개요 · Expo 준비 ~ 의 계속입니다.
이번 기사에서는 Redux를 사용하여 우선 간단한 카운터를 만들어 갑니다.
차례차례의 기사로 로그인 화면과 화면 천이를 구현해 나갈 예정입니다.
현재 디렉토리 구성
root/
├ App.js
├ package.json
src 디렉토리 만들기
root에 여러가지 넣어 가면 이해하기 어려워지므로, src 디렉토리를 만들어 App을 옮깁시다
Expo는 기본적으로 root/App.js를 로드하기 때문에 이를 변경하기 위해 node_modules/expo/AppEntry.js를 편집합니다.
/node_modules/expo/AppEntry.js-- import App from '../../App';
++ import App from '../../src/App';
그런 다음 root/App.js를 삭제하고 root/src/App.tsx를 작성합니다.
Redux 도입
우선 App.tsx에 redux를 넣습니다.
우선 최소한의 구성으로, 1 파일에 정리하고 있습니다
src/App.tsximport React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { createStore, combineReducers } from 'redux'
import { Provider, connect } from 'react-redux'
// reducer
function 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
}
}
// store
const store = createStore(combineReducers({ count: counter }))
// component
function Counter({ count, dispatch }) {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={() => dispatch({ type: 'INCREMENT' })}
/>
<Button
title='DECREMENT'
onPress={() => dispatch({ type: 'DECREMENT' })}
/>
</View>
)
}
// container
const CounterContainer = connect(state => ({ count: state.count }))(Counter)
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
// スタイル
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
})
Reducer
App.tsx// reducer
function 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
}
}
action과 현재의 state를 받고 새로운 state를 돌려주는 함수입니다.
action이 없거나 swich 문의 default에서 null을 반환하지 않으면 오류가 발생하므로주의가 필요합니다.
스토어
root/App.tsx// store
const store = createStore(combineReducers({ count: counter }))
Reducer가 향후 늘어나는 것을 근거로, combineReducer로 정리해 둡니다.
Component/Container
App.tsx// component
function Counter({ count, dispatch }) {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={() => dispatch({ type: 'INCREMENT' })}
/>
<Button
title='DECREMENT'
onPress={() => dispatch({ type: 'DECREMENT' })}
/>
</View>
)
}
// container
const CounterContainer = connect(state => ({ count: state.count }))(Counter)
화면에 표시하는 부분입니다.
버튼을 누르면 type이 INCREMENT/DECREMENT인 action이 dispatch됩니다.
버튼을 눌렀을 때의 콜백 함수는, 본래는 Container측에 써야 한다고는 생각합니다만, 코드가 조금 까다롭게 되기 때문에, 그것은 나중에 하려고 합니다.
앱
App.tsxexport default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
ReactNative는 로 둘러싸고 store를 전달하면 Redux와 연결할 수 있습니다.
여기까지 실행하면 이런 느낌
다음 번
이번은 최저 구성의 redux를 짜 보았으므로, 다음번은 Ducks 패턴을 의식해 파일을 나누어 가고 싶습니다.
그런 다음 ReactNativeDebugger도 사용할 수 있습니다.
Expo+Redux(+firebase)로 로그인 폼③~파일 정리·Debugger~
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼② ~Redux 도입~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/AtsushiNi/items/57851128a32020d2e1b8
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
root/
├ App.js
├ package.json
src 디렉토리 만들기
root에 여러가지 넣어 가면 이해하기 어려워지므로, src 디렉토리를 만들어 App을 옮깁시다
Expo는 기본적으로 root/App.js를 로드하기 때문에 이를 변경하기 위해 node_modules/expo/AppEntry.js를 편집합니다.
/node_modules/expo/AppEntry.js-- import App from '../../App';
++ import App from '../../src/App';
그런 다음 root/App.js를 삭제하고 root/src/App.tsx를 작성합니다.
Redux 도입
우선 App.tsx에 redux를 넣습니다.
우선 최소한의 구성으로, 1 파일에 정리하고 있습니다
src/App.tsximport React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { createStore, combineReducers } from 'redux'
import { Provider, connect } from 'react-redux'
// reducer
function 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
}
}
// store
const store = createStore(combineReducers({ count: counter }))
// component
function Counter({ count, dispatch }) {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={() => dispatch({ type: 'INCREMENT' })}
/>
<Button
title='DECREMENT'
onPress={() => dispatch({ type: 'DECREMENT' })}
/>
</View>
)
}
// container
const CounterContainer = connect(state => ({ count: state.count }))(Counter)
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
// スタイル
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
})
Reducer
App.tsx// reducer
function 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
}
}
action과 현재의 state를 받고 새로운 state를 돌려주는 함수입니다.
action이 없거나 swich 문의 default에서 null을 반환하지 않으면 오류가 발생하므로주의가 필요합니다.
스토어
root/App.tsx// store
const store = createStore(combineReducers({ count: counter }))
Reducer가 향후 늘어나는 것을 근거로, combineReducer로 정리해 둡니다.
Component/Container
App.tsx// component
function Counter({ count, dispatch }) {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={() => dispatch({ type: 'INCREMENT' })}
/>
<Button
title='DECREMENT'
onPress={() => dispatch({ type: 'DECREMENT' })}
/>
</View>
)
}
// container
const CounterContainer = connect(state => ({ count: state.count }))(Counter)
화면에 표시하는 부분입니다.
버튼을 누르면 type이 INCREMENT/DECREMENT인 action이 dispatch됩니다.
버튼을 눌렀을 때의 콜백 함수는, 본래는 Container측에 써야 한다고는 생각합니다만, 코드가 조금 까다롭게 되기 때문에, 그것은 나중에 하려고 합니다.
앱
App.tsxexport default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
ReactNative는 로 둘러싸고 store를 전달하면 Redux와 연결할 수 있습니다.
여기까지 실행하면 이런 느낌
다음 번
이번은 최저 구성의 redux를 짜 보았으므로, 다음번은 Ducks 패턴을 의식해 파일을 나누어 가고 싶습니다.
그런 다음 ReactNativeDebugger도 사용할 수 있습니다.
Expo+Redux(+firebase)로 로그인 폼③~파일 정리·Debugger~
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼② ~Redux 도입~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/AtsushiNi/items/57851128a32020d2e1b8
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
-- import App from '../../App';
++ import App from '../../src/App';
우선 App.tsx에 redux를 넣습니다.
우선 최소한의 구성으로, 1 파일에 정리하고 있습니다
src/App.tsx
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { createStore, combineReducers } from 'redux'
import { Provider, connect } from 'react-redux'
// reducer
function 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
}
}
// store
const store = createStore(combineReducers({ count: counter }))
// component
function Counter({ count, dispatch }) {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={() => dispatch({ type: 'INCREMENT' })}
/>
<Button
title='DECREMENT'
onPress={() => dispatch({ type: 'DECREMENT' })}
/>
</View>
)
}
// container
const CounterContainer = connect(state => ({ count: state.count }))(Counter)
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
// スタイル
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
})
Reducer
App.tsx
// reducer
function 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
}
}
action과 현재의 state를 받고 새로운 state를 돌려주는 함수입니다.
action이 없거나 swich 문의 default에서 null을 반환하지 않으면 오류가 발생하므로주의가 필요합니다.
스토어
root/App.tsx
// store
const store = createStore(combineReducers({ count: counter }))
Reducer가 향후 늘어나는 것을 근거로, combineReducer로 정리해 둡니다.
Component/Container
App.tsx
// component
function Counter({ count, dispatch }) {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>{count}</Text>
<Button
title='Increment'
onPress={() => dispatch({ type: 'INCREMENT' })}
/>
<Button
title='DECREMENT'
onPress={() => dispatch({ type: 'DECREMENT' })}
/>
</View>
)
}
// container
const CounterContainer = connect(state => ({ count: state.count }))(Counter)
화면에 표시하는 부분입니다.
버튼을 누르면 type이 INCREMENT/DECREMENT인 action이 dispatch됩니다.
버튼을 눌렀을 때의 콜백 함수는, 본래는 Container측에 써야 한다고는 생각합니다만, 코드가 조금 까다롭게 되기 때문에, 그것은 나중에 하려고 합니다.
앱
App.tsx
export default function App() {
return (
<Provider store={store}>
<CounterContainer />
</Provider>
)
}
ReactNative는 로 둘러싸고 store를 전달하면 Redux와 연결할 수 있습니다.
여기까지 실행하면 이런 느낌
다음 번
이번은 최저 구성의 redux를 짜 보았으므로, 다음번은 Ducks 패턴을 의식해 파일을 나누어 가고 싶습니다.
그런 다음 ReactNativeDebugger도 사용할 수 있습니다.
Expo+Redux(+firebase)로 로그인 폼③~파일 정리·Debugger~
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼② ~Redux 도입~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/AtsushiNi/items/57851128a32020d2e1b8
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Expo+Redux(+firebase)로 로그인 폼② ~Redux 도입~), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/AtsushiNi/items/57851128a32020d2e1b8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)