React Native и Redux Persist не сохраняют состояние в постоянное хранилище

Я создал образец приложения React Native, чтобы посмотреть, смогу ли я заставить Redux-persist работать. Однако мое приложение React Native с Redux Persist не сохраняет состояние в постоянное хранилище.

Каждый раз, когда я меняю переключатель на «истина», а затем перезагружаю приложение, состояние не сохраняется и возвращается к нулю.

Как сделать так, чтобы значение True оставалось неизменным при обновлении приложения.

Вот мой код:

index.js:

import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
import React, {Component} from 'react';
import { Provider } from "react-redux";
import { store, persistor } from "./Store/index";
import { PersistGate } from 'redux-persist/integration/react'
import App from './App.js';

class ReduxPersistTest extends Component {

render() {
  return (
    <Provider store={store}>
      <PersistGate persistor={persistor} loading={null}>
      <App />
      </PersistGate>
    </Provider>
          );
        }
      }

AppRegistry.registerComponent('ReduxPersistTest', () => ReduxPersistTest);

магазин / index.js:

import { createStore, applyMiddleware, compose } from "redux";
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';
import toggle from "../Reducers/rootReducer.js";

import { AsyncStorage } from "react-native";
import {persistStore, persistReducer, persistCombineReducers} from "redux-persist";
import storage from 'redux-persist/lib/storage'
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';

const togglePersistConfig = {
  key: 'toggle',
  storage: AsyncStorage
};

const middleware = [thunk];

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  debug: true,
  whitelist: ['toggle']
}

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const reducers = { toggle: persistReducer(togglePersistConfig, toggle) };
const persistedReducer = persistCombineReducers(persistConfig, reducers);


export const store = createStore(
  persistedReducer, composeEnhancers(applyMiddleware(...middleware))
);


export const persistor = persistStore(store);

Reducer.js

Проблема может быть обнаружена здесь, в моем редукторе ...

import { ADD_TOGGLE } from "../Constants/action-types";

import { combineReducers } from 'redux';


const initialState = {
  toggle: false,
};

const rootReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_TOGGLE:
    console.log(action.payload.toggle);
    console.log(action.payload);
    return {
      ...state, toggle: {
        toggle: action.payload.toggle,
    }};
    default:
      return state;
  }
};


export default rootReducer;

Действия / index.js

import { ADD_TOGGLE } from "../Constants/action-types";

export const addToggle = toggle => ({ type: ADD_TOGGLE, payload: toggle });

Константы / action-Types.js

export const ADD_TOGGLE = "ADD_TOGGLE";

И мои компоненты:

App.js

import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';

import Copy from './Components/Copy/Copy.js';
import CopyToggle from './Components/Copy/CopyToggle.js';

/*
Redux imports
*/
import { connect } from "react-redux";
import { addToggle } from "./Actions/index";

/*
Redux constants
*/
const mapDispatchToProps = dispatch => {
  return {
    addToggle: toggle => dispatch(addToggle(toggle))
  };
};

//Styles
const styles = StyleSheet.create({
  textHeader: {
    textAlign: 'center',
    marginBottom: 10,
    marginTop: 100,
  },
});

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
          toggle: false,
        };
  }

  componentWillMount() {
    const { toggle } = this.state;
    this.props.addToggle({ toggle });
  }

render() {
  return (
    <View>
      <Text style={styles.textHeader}>Welcome to React Native!</Text>
      <Copy />
      <CopyToggle />
    </View>
        )
      }
    }

export default connect(null, mapDispatchToProps)(App);

Copy.JS (переключите пользовательский интерфейс, чтобы изменить значение переключателя с «true» на «false»

    import React, { Component } from 'react';
    import {Platform, StyleSheet, Text, View} from 'react-native';

    import { compose } from 'react-compose';
    import { Switch } from 'react-native-switch';

    import { connect } from "react-redux";
    import { addToggle } from "../../Actions/index";

    const mapDispatchToProps = dispatch => {
      console.log('mapDispatchToProps hit');
      return {
        addToggle: toggle => dispatch(addToggle(toggle))
      };
    };


    class Copy extends Component {
      constructor(props) {
        super(props);

        this.state = {
          toggle: false,
        };

        this.addtoggle = this.addtoggle.bind(this);

      }

      addtoggle(val) {
        this.setState({
          toggle: val,
        }, function () {
          const { toggle } = this.state;
          this.props.addToggle({ toggle });
        });
      }


      render() {
        return (
            <View>
              <Text>Test redux persist</Text>
              <Switch
      value={ this.state.toggle }
      onValueChange={(val) => this.addtoggle(val)}
    />
            </View>
        );
      }
    }

    export default connect(null, mapDispatchToProps)(Copy);

CopyToggle.js (выводит логическое значение переключателя)

import React, { Component } from 'react';

/*
Redux imports
*/
import { connect } from "react-redux";
import { addToggle } from "../../Actions/index";

/*
Native base and react native
*/
import { StyleSheet, View, Text } from 'react-native';

/*
Redux constants
*/
const mapDispatchToProps = dispatch => {
  return {
    addToggle: toggle => dispatch(addToggle(toggle))
  };
};

const mapStateToProps = state => {
  return { toggle: state.toggle.toggle };
};

// Custom Styles
const styles = StyleSheet.create({
  textHeader: {
    color: '#000',
  },
});


//class
class CopyToggle extends Component {
  constructor(props) {
    super(props);
      this.state = {
        purchase: false,
      };
this.toggleDisplay = this.toggleDisplay.bind(this);
  }

  componentWillMount() {
    const { toggle } = this.state;
    this.props.addToggle({ toggle });
  }

//display to output bollean value
  toggleDisplay() {
    let toggleState;
    if (this.props.toggle === false) {
      toggleState = 'false'
    }
    else if (this.props.toggle === true) {
      toggleState = 'true'
    }
    return (
      <Text>{toggleState}</Text>
    )
  }

//render
  render() {
    return (
      <View>
        {this.toggleDisplay()}
      </View>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(CopyToggle);

Мы будем очень признательны, если кто-то со знанием Redux может просмотреть и, надеюсь, указать на мою проблему.

Благодарность!


person Andrew Oxley    schedule 28.11.2018    source источник


Ответы (2)


Вам нужно использовать persistCombineReducers, если вы хотите сохранить только часть вашего магазина, поэтому я бы придумал что-то похожее на это:

import { persistCombineReducers, persistReducer } from 'redux-persist';

import toggle from './Reducer.js';

const togglePersistConfig = {
  key: 'toggle',
  storage: AsyncStorage
};

const reducers = {
  toggle: persistReducer(togglePersistConfig, toggle),
  // ...other reducers
}

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
  debug: true,
  whitelist: ['toggle']
};

const persistedReducer = persistCombineReducers(persistConfig, reducers);

export const store = createStore( persistedReducer, composeEnhancers(applyMiddleware(...middleware)) );
person ddavydov    schedule 28.11.2018
comment
Спасибо @ddavydov. Как мне добавить это в свой магазин? Я отредактировал свой исходный пост на store / index.js: попытался добавить ваше предложение. Если вы можете помочь, мы будем очень признательны. - person Andrew Oxley; 29.11.2018
comment
В вашем магазине / index.js: const reducers = { toggle: persistReducer(persistConfig, toggle) }; const persistedReducer = persistCombineReducers(persistConfig, reducers); export const store = createStore( persistedReducer, composeEnhancers(applyMiddleware(...middleware)) ); - person ddavydov; 29.11.2018

Вы должны добавить значение, которое хотите сохранить в объекте хранилища:

AsyncStorage.setItem('toggle': this.state.toggle)

person Anis D    schedule 28.11.2018
comment
Спасибо @ anis-d. Я добавил ниже в Copy.js, но все еще не сохранился. addtoggle (val) {this.setState ({toggle: val,}, function () {const {toggle} = this.state this.props.addToggle ({toggle});}, () = ›{AsyncStorage .setItem (this.state.toggle)}); } - person Andrew Oxley; 29.11.2018
comment
Извините, я обновил свой набор ответов. Элемент должен принимать объект - person Anis D; 30.11.2018