ReactNativeでstyled-componentsを使う

StyleSheet.createを使う書き方は辛すぎるので、styled-componentsを組み合わせて使うサンプルを書いてみました。
以下のような簡単なカウンターです。

<img src="https://camo.githubusercontent.com/5183b9fac8f13f8524aaf891d98d167290ff897a/68747470733a2f2f692e6779617a6f2e636f6d2f30396564383933363431666362613262613965323862643130313461333231372e706e67"  height="500"/>

[**akameco/react-native-counter-with-styled-components**](https://github.com/akameco/react-native-counter-with-styled-components)

create-react-native-appを使いました。
環境構築をしなくていいのは楽ですね。

```
$ create-react-native-app sample-app
```

短いので、全コードを記載します。
App.jsにコピペすれば動くと思います。
styled-componentsを使うとJSXが簡潔になっていいですね。
また、underlayColorなどのアトリビュートまわりなど明快になると思います。


```js
// @flow
import * as React from 'react'
import { TouchableHighlight } from 'react-native'
import { css } from 'styled-components'
import styled from 'styled-components/native'

const center = css`
  justify-content: center;
  align-items: center;
`

const inline = css`
  flex-direction: row;
  align-items: flex-end;
`

const Container = styled.View`
  flex: 1;
  ${center};
  background-color: #f5fcff;
`

const Panel = styled.View`
  margin-top: 30px;
  ${p => p.inline && inline};
`

const Block = styled.Text`
  font-weight: bold;
  align-self: flex-end;
`

const NumberBlock = Block.extend`
  font-size: 100px;
  text-align: center;
`

const UnitBlock = Block.extend`font-size: 16px;`

const Button = styled(TouchableHighlight).attrs({
  underlayColor: p => (p.add ? '#ffc1d6' : '#d0dff9'),
})`
  ${center};
  height: 50px;
  margin: 10px;
  border-radius: 10px;
  border-color: ${p => (p.add ? '#f69' : '#6495ed')};
  border-width: 2px;
  padding-left: 10px;
  padding-right: 10px;
`

const SmallButton = Button.extend`height: 40px;`

const StyledText = styled.Text`
  color: ${p => (p.add ? '#f69' : '#6495ed')};
  font-size: 20px;
  font-weight: bold;
  text-align: center;
`

const delay = (ms: number = 1000) =>
  new Promise(resolve => {
    setTimeout(() => {
      resolve()
    }, ms)
  })

class Counter extends React.Component<{}, { count: number }> {
  state = { count: 0 }
  _changeCount = n => {
    this.setState({ count: this.state.count + n })
  }
  increment = () => this._changeCount(+1)
  decrement = () => this._changeCount(-1)
  incrementIfOdd = () => {
    if (this.state.count % 2 !== 0) {
      this.increment()
    }
  }
  incrementAsync = async () => {
    await delay()
    this.increment()
  }
  decrementAsync = async () => {
    await delay()
    this.decrement()
  }
  render() {
    return (
      <Container>
        <Panel inline>
          <NumberBlock>{this.state.count}</NumberBlock>
          <UnitBlock>/ times</UnitBlock>
        </Panel>
        <Panel inline>
          <SmallButton add onPress={this.increment}>
            <StyledText add>+</StyledText>
          </SmallButton>
          <SmallButton onPress={this.decrement}>
            <StyledText>-</StyledText>
          </SmallButton>
        </Panel>
        <Panel>
          <Button add onPress={this.incrementIfOdd}>
            <StyledText add>Increment if odd</StyledText>
          </Button>
          <Button add onPress={this.incrementAsync}>
            <StyledText add>Increment async</StyledText>
          </Button>
          <Button onPress={this.decrementAsync}>
            <StyledText>Decrement async</StyledText>
          </Button>
        </Panel>
      </Container>
    )
  }
}

export default Counter
```

ReactNativeをほぼ書いていないアプリ初心者ですので、何か間違いがありましたら、コメント欄やTwitterにて教えていただけるとうれしいです。


<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">styled-componentsとReactNativeとExpoの組み合わせは最高 <a href="https://t.co/KnrbR7lAaH">pic.twitter.com/KnrbR7lAaH</a></p>&mdash; 無職.js (@akameco) <a href="https://twitter.com/akameco/status/903892994998153216">September 2, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>