LoginSignup
0
1

More than 3 years have passed since last update.

React Nativeでredux-persistを簡単に導入

Posted at

React Nativeでアプリを開発するときに、デバイスのストレージにデータを保存したいときに、Storeの永続化に使えるredux-persistが便利です。
しかし、さほど複雑なデータを扱わなくとも、Reduxの導入が必須になります。
個人的には、Reduxを導入するには複雑なファイル群がどうしてもハードル高く思ってしまいました。
世界一シンプルなReactNative + Reduxチュートリアル①
この記事を参考して、とってもシンプルにReduxを導入できました。
とっても助かりました。

上記踏まえて、
・ インターフェイス上1Tapで複数のStateを変更するイベント処理をView側の関数に入れて、一旦中継してからStoreへ渡すようにする
・ redux-persistの導入を加える

ことを加味したコードの一部をご紹介します。

事前準備

必要なライブラリをインストール

npm install --save redux react-redux redux-persist react-native-asyncstorage

コード部分

redux部分

actions.js, reducers.js, store.jsを一つのファイルにまとめます
redux-persistを導入し、AsyncStorageに保存します。

redux.js
// redux.js
import { combineReducers, createStore } from 'redux';
import { persistReducer, persistStore } from 'redux-persist';
import { AsyncStorage } from 'react-native';

// actions.js
export const addItem = (inputText1, inputText2) => ({
  type: 'ADD_ITEM',
  inputText1: inputText1,
  inputText2: inputText2
});

export const deleteItem = (targetIndex) => ({
  type: 'DELETE_ITEM',
  targetIndex: targetIndex
});

const INITIAL_STATE = {
  listData: [],
  currentIndex: 0,
}

// reducers.js
const reducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case 'ADD_ITEM':
      const newList = {
        inputText1: action.inputText1,
        inputText2: action.inputText2,
        key: state.currentIndex + 1
      }
      return {
        ...state,
        listData: [...state.listData, newList],
        currentIndex: state.currentIndex + 1
      }
    case 'DELETE_ITEM':
      const targetIndex = action.targetIndex + 1;
      console.log(targetIndex)
      const newlistData = state.listData.filter(function(v){
        return v.key != targetIndex;
      });
      console.log(newlistData)
      return {
        ...state,
        listData: newlistData,
      }

    default:
      return state;
  }
}

export const reducers = combineReducers({
  listData: reducer
})

// store.js
const persistConfig = {
  key: 'MAIN',
  storage: AsyncStorage,
}

const persistedReducer = persistReducer(persistConfig, reducers)
const store = createStore(persistedReducer)
export const persistor = persistStore(store)
export default store
console.log(store)

スクリーンの部分

一部のStoreには渡さないstateのイベントはここの中で完結します。

Screen.js
import React from 'react';
import { Text, View, ScrollView, FlatList } from 'react-native';
import { Input, Button, ListItem } from 'react-native-elements';
import { connect } from 'react-redux';
import { addItem, deleteItem } from './redux';
import { store } from './redux';

class MainScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputText1: "",
      imageText2: "",
      targetIndex: ""
    };
  }
  addData = () => {
     this.props.addItem(this.state.inputText1, this.state.inputText2)
     this.setState({inputText: "", imageUrl: ""});
   }
   deleteData = (item) => {
     const targetIndex = item.key - 1;
     this.props.deleteItem(targetIndex)
   }

  render() {
    let listContents = this.props.listData;
    return (
      <React.Fragment>
        <ScrollView>
        <FlatList data={listContents}
          extraData={this.state}
          renderItem={({item}) =>
            <ListItem key={"listItem_" + item.key} title={item.inputText1 + item.inputText2} onPress={() => this.deleteData(item)} />
          }
          keyExtractor={(item, index) => "todo_" + item.index}
        />
      </ScrollView>
      <View>
        <Input
          onChangeText={(text) => this.setState({inputText1: text})}
          value={this.state.inputText1}
          keyboardType="default"
          returnKeyType="done"
        />
        <Input
          onChangeText={(text) => this.setState({inputText2: text})}
          value={this.state.inputText2}
          keyboardType="default"
          returnKeyType="done"
        />
        <Button title="Add" onPress={this.addData} />
      </View>
    </React.Fragment>);
  }
}

const mapStateToProps = state => ({
  listData: state.listData.listData
})

const mapDispatchToProps = {
  addItem,
  deleteItem
}

export default connect(mapStateToProps, mapDispatchToProps)(Screen)

書き出す部分

必要なものをインポートし、PersistGateを加えます。

App.js
import React from 'react';
import { Provider } from "react-redux";
import store, { persistor } from "./redux";
import { PersistGate } from 'redux-persist/integration/react'
import MainScreen from './Screen';

export default class App extends React.Component {
  render () {
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <Screen />
        </PersistGate>
      </Provider>
    )
  }
}

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1