ワイ最近、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の時のみ使える方法やで!
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
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の得意なプロトタイプ制作やスタートアップには適さない