Skip to content

Instantly share code, notes, and snippets.

@yayamochi
Last active October 31, 2018 05:10
Show Gist options
  • Save yayamochi/f147eec1a15206961b2159b57f8b393f to your computer and use it in GitHub Desktop.
Save yayamochi/f147eec1a15206961b2159b57f8b393f to your computer and use it in GitHub Desktop.
ReactNative+Typescript+Reduxの構成でアプリ作成(ios) ref: https://blog.yayawatanabe.net/entry/2018/10/30/211910
import React from 'react'
import { Provider } from 'react-redux'
import store from '../store'
import { StyleSheet, ViewStyle, SafeAreaView, View } from 'react-native'
import TextFormContainer from '../containers/TextFormContainer'
import ItemsContainer from '../containers/ItemsContainer'
interface Props {}
interface State {}
export default class Main extends React.Component<Props, State> {
render() {
return (
<Provider store={store}>
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TextFormContainer />
<ItemsContainer />
</View>
</SafeAreaView>
</Provider>
)
}
}
interface Style {
container: ViewStyle
}
const styles = StyleSheet.create<Style>({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#CCCCCC'
}
})
$ yarn add react-redux redux remote-redux-devtools
$ yarn add --save-dev @types/react @types/react-native @types/react-redux @types/remote-redux-devtools tslint tslint-config-prettier tslint-plugin-prettier tslint-react typescript
sample-app/
 ├ android/
 ├ ios/
 ├ src/
 │ └ actions/
 │  └ types.ts
 │  └ index.ts
 │ └ components/
 │  └ Items.tsx
 │  └ TextForm.tsx
 │ └ containers/
 │  └ ItemsContainer.ts
 │  └ TextFormContainer.ts
 │ └ reducers/
 │  └ index.ts
 │  └ items.ts
 │ └ screens/
 │  └ App.tsx
 │ └ store/
 │  └ index.ts
 │
 ├ index.js
 └ (略)
sample-app/
 ├ src/
 │ └ screens/
 │  └ App.tsx
/** @format */
import { AppRegistry } from 'react-native'
import App from './src/screens/App'
import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App)
import reducers from "../reducers"
import { createStore } from "redux"
import devToolsEnhancer from "remote-redux-devtools"
const store = createStore(reducers, devToolsEnhancer())
export default store
import { ADD_ITEM, EDITING_ITEM } from "../actions/types"
const initialState: {
editing_title: string
items: { id: number; title: string }[]
} = { editing_title: "", items: [] }
export const items = (state = initialState, action: any): any => {
switch (action.type) {
case ADD_ITEM:
return {
...state,
items: [
...state.items,
{
id: action.id,
title: state.editing_title,
},
],
}
case EDITING_ITEM:
return {
...state,
editing_title: action.editing_title,
}
default:
return state
}
}
export default items
import React, { Component } from 'react'
import { Text, FlatList } from 'react-native'
interface Props {
items: { id: number; title: string }[]
}
export default class Items extends Component<Props> {
render() {
let items = this.props.items
return (
<FlatList
data={items}
renderItem={({ item }) => <Text>{item.title}</Text>}
keyExtractor={item => `${item.id}`}
/>
)
}
}
import Items from '../components/Items'
import { connect } from 'react-redux'
const mapStateToProps = (state: any) => {
return { items: state.items.items }
}
export default connect(mapStateToProps)(Items)
import React, { Component } from 'react'
import {
TextInput,
View,
Text,
StyleSheet,
TouchableOpacity,
ViewStyle,
TextStyle
} from 'react-native'
interface Props {
addItem: () => void
editingItem: (text: string) => void
items: { id: number; title: string }[]
}
export default class TextForm extends Component<Props> {
render() {
return (
<View style={styles.container}>
<TextInput
style={styles.textInput}
onChangeText={text => this.props.editingItem(text)}
/>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.addItem()}
>
<Text style={styles.buttonText}>追加</Text>
</TouchableOpacity>
</View>
)
}
}
interface Style {
container: ViewStyle
textInput: ViewStyle
button: ViewStyle
buttonText: TextStyle
}
const styles = StyleSheet.create<Style>({
container: {
flexDirection: 'row',
padding: 20
},
textInput: {
flex: 3,
backgroundColor: '#FFF',
marginRight: 5
},
button: {
flex: 1,
backgroundColor: '#F58E7E',
marginLeft: 5,
alignItems: 'center',
justifyContent: 'center',
paddingTop: 10,
paddingBottom: 10
},
buttonText: {
color: '#FFF',
fontWeight: 'bold'
}
})
import TextForm from '../components/TextForm'
import { addItem, editingItem } from '../actions'
import { connect } from 'react-redux'
const mapStateToProps = (state: any) => {
return { items: state.items }
}
const mapDispatchToProps = (dispatch: any) => {
return {
addItem: () => {
dispatch(addItem())
},
editingItem: (text: string) => {
dispatch(editingItem(text))
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(TextForm)
export const ADD_ITEM = "ADD_ITEM"
export const EDITING_ITEM = "EDITING_ITEM"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment