React Native и Redux Persist не сохраняют состояние в постоянное хранилище - PullRequest
0 голосов
/ 28 ноября 2018

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

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

Как я могу получить «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);

store / 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;

Действия / индекс.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);

Копировать.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 persist, сможет просмотреть и, надеюсь, указать на мою проблему.

СПАСИБО!

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Вам нужно использовать 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)) );
0 голосов
/ 28 ноября 2018

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

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

...