redux-persistを使わずに、ReactNativeのstateを永続化する！

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
ワイ最近、reduxを使うのを止めたんや。
そいで、気づいたんやredux-persistが使えない。
何でや？？？？
yarn add redux-persistしてるんやで。
redux-persistにissue建てな！

仕方がないからバニラreact nativeで、手軽に、stateや、propsを保存する方法を考えたんや！

## 仕方ないから、redux-persistにプルリクすることにしたんや。
「**redux-persistと、reduxを使わずに**、stateをデータベースに保存するコードをかいたので、マージしてください。」
って。

返信は帰って来なかったやで。
日本語で書いたのが悪かったんやろか？
いや、ワイが日本語読めるんやから、ライブラリ作るくらい優秀な人は、日本語ぐらい読めるはずやで、
何が問題なんやーーー

## ちなみに、以下のコードをプルリクしたやで。
componentDidMountで、stateをAsyncStorageから読み込み、
componentDidUpdateで、stateに変化があるたびにAsyncStorageに保存する
単純なコードや。
setStateが発火するたびにasyncStorageにstateを丸ごと保存するやで。
ただ、巨大なjsonを、parseするのは、時間がかかるので小さなstateの時のみ使える方法やで!

```jsx
import React, { Component } from 'react'
import { StyleSheet, Text, View, AsyncStorage } from 'react-native'

const retrieveData = async str => {
  try {
    const value = await AsyncStorage.getItem(str)
    if (value !== null) {
      return value
    } else {
      return null
    }
  } catch (error) {
    return null
  }
}

const storeData = async (key, value) => {
  try {
    await AsyncStorage.setItem(key, value)
  } catch (error) {
    
  }
}

export default class App extends Component {
  state = {
    counter: 0
  }

  componentDidMount = () => {
    this.setInitialState()
  }

  setInitialState = async () => {
    const initialState = await retrieveData('App')
    if (initialState) {
      const parsedState = await JSON.parse(initialState)
      this.setState(parsedState)
    }
  }

  componentDidUpdate (prevProps, prevState) {
    if (this.state !== prevState) {
      const stringifiedState = JSON.stringify(this.state)
      storeData('App', stringifiedState)
    }
  }

  increment = () => {
    this.setState({ counter: this.state.counter + 1 })
  }

  render () {
    return (
      <View style={styles.container}>
        <Text onPress={() => this.increment()}>increment</Text>
        <Text>{this.state.counter}</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
})
```

小規模なら、案外使える！
でも、ちょっと大きなデータを食わせると目に見えて遅くなる。
なんてこった。facebook! AsyncStorageは粗大ゴミだぞ！

そこで、AsyncStorageの代わりに、react-native-storageを使ったところ全てがうまくいった。
ちょっと大きいデータをセーブしてもロードしても、早い！

だいたい以下のようなコードを、実務でredux-persistの代わりに使っている。

```
yarn add react-native-storage
```

```jsx
import React, { Component } from 'react'
import { StyleSheet, Text, View, AsyncStorage } from 'react-native'
import Storage from 'react-native-storage'

// storageを作成
const storage = new Storage({
  storageBackend: AsyncStorage
})

export default class App extends Component {
  state = {
    counter: 0
  }

  // this.constructor.displayNameで、自身のクラス名を取得
  className = this.constructor.displayName

  componentDidMount = () => {
    this.setInitialState()
  }

  setInitialState = async () => {
    // react-native-storageは、読み込みがとても速い
    storage
      .load({ key: this.className })
      .then(res => this.setState(res))
      .catch(err => console.warn(err))
  }

  componentDidUpdate (prevProps, prevState) {
    if (this.state !== prevState) {
      // stateに変化があったら、this.stateを丸ごと保存する。
      // react-native-storageは速いので、丸ごと保存しても大丈夫
      storage.save({
        key: this.className,
        data: this.state
      })
    }
  }

  increment = () => {
    this.setState({ counter: this.state.counter + 1 })
  }

  render () {
    return (
      <View style={styles.container}>
        <Text onPress={() => this.increment()}>increment</Text>
        <Text>{this.state.counter}</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
})
```

あんなに素晴らしいと感じていたreduxが今ではゴミのように思える。
reduxは今でも好きだけど、react-nativeの得意なプロトタイプ制作やスタートアップには適さない