如何在React Native中使用Redux Persist

1,011 阅读7分钟

有时,开发人员需要在本地为用户保存信息。例如,假设你建立了一个电子商务平台,用户可以在不登录的情况下向他们的购物车添加物品。你需要实现一种方法,让应用程序记住用户添加到购物车中的物品。如果用户暂时关闭应用程序,却发现他们添加到购物车的物品已经不在那里了,这将是一种糟糕的体验。

另一种情况是,当用户登录到你的应用后,他们关闭应用一分钟,却被带到登录页面再次登录。

在这篇文章中,我们将学习如何使用Redux Persist来持久化Redux商店。首先,我们将建立一个小型的待办事项应用程序,并用Redux设置其状态管理。然后,我们将设置Redux Persist库,以便在应用被关闭的情况下保存数据。让我们开始吧!

Redux Persist和React Native

在React Native应用中,数据可以使用AsyncStorage 进行本地持久化。AsyncStorage 是一个异步的、持久的、键值存储系统,对整个应用来说是全局性的。

Redux Persist是一个工具,用于无缝保存应用程序的Redux状态对象AsyncStorage 。在应用启动时,Redux Persist检索这个持久化的状态并将其保存回Redux。

通常情况下,Redux在启动时设置你的应用程序的初始状态。不久之后,Redux Persist会获取你的持久化状态,在Redux Persist团队称之为补水的过程中覆盖任何初始状态。

Redux 是一个开源的JavaScript库,用于管理和集中应用状态。它将整个应用程序的状态维护在一个单一的不可变的状态对象中,该对象不能直接改变。当某些东西发生变化时,会使用动作和还原器创建一个新的对象。

设置项目

在本教程中,我们将演示在Expo snack平台上实现Redux Persist。

让我们创建一个名为screens 的文件夹。在它里面,创建一个名为Todo.js 的文件,它将包含添加待办事项的输入字段,同时也显示添加的待办事项。

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

export default function BooksListApp() {
  return (
    <View style={styles.container}>
        <Text style={styles.paragraph}>React Native ToDo App with Redux Persist </Text>
          <Text style={styles.title}> Add ToDo Here</Text>
          <TextInput
            style={styles.input}
            mode="outlined"
            label="Task"
            value={task}
             onChangeText={task => setTask(task)}
          />
          <Button title='Add' color="#841584"  />
      <FlatList
        data={todos}
        keyExtractor={(item) => item.id}
        renderItem={({item, index}) => {
          return (
              <Text style={styles.list}>{item.task}</Text>
          );
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 10,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
  title: {
    margin: 10,
    fontSize: 16,
    fontWeight: 'bold',
    textAlign: 'center',
  },
  list: {
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
  input: {
    height: 40,
    margin: 12,
    borderWidth: 1,
    padding: 10,
  },
});

设置Redux

要设置Redux,首先用以下代码安装它。

npm install redux

创建动作创建者

使用Redux,整个应用程序的状态由一个JavaScript对象管理。为了对该对象进行修改,我们可以调度动作。

让我们创建另一个名为redux 的文件夹,用于状态管理。在它里面,让我们创建一个action.js 文件来设置动作类型和动作创建者。

export const ADD_TODO = "ADD_TODO";

let todoId = 0;

export const addTodo = task => ({
  type: ADD_TODO,
  payload: {
    id: ++todoId,
    task
  }
});

动作类型ADD_TODO 是不言自明的。当我们需要通过添加一个新的todo来更新状态时,我们会调用它。

创建还原器

当一个动作被派发后,一个还原器通过对状态对象的改变来更新状态。还原器是一个纯函数,需要两个输入,状态和动作,并且必须返回默认状态。

让我们在redux 文件夹中创建另一个文件并导入我们之前创建的动作类型。我们还将创建一个初始应用状态。

import { ADD_TODO } from "./action";

const initialState = {
  todos: []
};

const todoReducer = (state = initialState, action) => {
  switch (action.type) {
    case ADD_TODO: {
      const { id, task } = action.payload
      return {
        ...state,
        todos: [ ...state.todos, { id, task }]
      };
    }
    default:
      return state;
  }
}

export default todoReducer;

在上面的代码中,我们定义了一个reducer函数,todoReducer ,它把initialState 作为第一个参数的默认值,把action 作为第二个参数。

设置Redux存储

Redux存储在应用层面上保存状态,以便可以从任何组件中访问它。Redux存储是一个对象,将行动和还原器结合在一起。

我们将使用Redux的createStore 方法来配置Redux商店。它把reducer作为一个参数。

redux 文件夹内创建一个store.js 文件,并按如下方式初始化Redux存储。

import { createStore } from "redux";
import todoReducer from './reducers';

export default createStore(todoReducer);

接下来,我们将通过将整个应用包裹在一个名为Provider 的高阶组件中,并将商店传递给它,使Redux商店全局可用。

App.js 文件中,从React Redux中导入Provider ,并将应用包裹在其中。

import store from './redux/store';
import { Provider } from 'react-redux';

const App = () => {
  return (
    <Provider store={store}>
      <MyTodo/>
    </Provider>
  );
}

export default App;

在上面的代码中,我们已经在React组件和Redux的存储和状态之间建立了联系。因此,这个应用程序中的任何组件都可以在任何时候访问应用程序的状态。

派遣一个动作

有了Redux的设置,让我们写一个函数,当用户添加一个待办事项时调度一个动作。在Todo.js ,添加下面的代码。

import { useSelector, useDispatch } from 'react-redux';
import { addTodo } from './redux/action';

const [task, setTask] = React.useState('');
  const  todoList  = useSelector(state => state.todos);
  const dispatch = useDispatch();


  const handleAddTodo = () => {
    dispatch(addTodo(task))
    setTask('')
  }

我们从React Redux中导入了useSelector Hook,用于获取这个组件中的状态,而useDispatch ,用于调度一个动作。然后,当Add 按钮被点击时,我们调用该函数。

<Button title='Add' color="#841584" onPress={handleAddTodo} />

现在,当我们在输入框中添加一个项目并点击按钮时,addTodo 动作创建者被调用,反过来,它将ADD_TODO 动作分派给reducer,这样项目就被添加,应用程序的状态就被更新。

在这一点上,你会注意到还原器正在工作,我们的待办事项应用已经启动并运行。但是,你会注意到,当我们关闭应用程序一段时间后再次打开时,我们添加的所有项目都不见了,这表明Redux状态已经被重置为初始状态。

我们可以使用Redux Persist将我们添加的项目持久化。因此,即使我们关闭应用程序并再次打开它,我们也不会丢失我们的待办事项。

整合Redux persist

让我们用以下命令安装Redux Persist包和React NativeAsyncStorage 包。

npm i redux-persist @react-native-async-storage/async-storage

我们将从Redux Persist导入persistStore, persistReducer ,并添加以下配置。

import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' 

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
}

为了创建React Persist的配置,你要传递密钥和存储引擎,这是必须的。还有其他可选的配置,如whitelistblacklistversionstateReconcilerdebug 。如果你不想持久化状态的一部分,你可以把它放在blacklist 。另外,whitelist 定义了你希望持久化的状态的部分。

现在,我们将调用persistReducer ,传入配置对象和我们的todoReducer
我们还导出了persistor ,这是一个由persistStore 返回的对象,它包裹着原始存储。

const persistedReducer = persistReducer(persistConfig, todoReducer)

export const store = createStore(persistedReducer)
export const persistor = persistStore(store)

在配置结束时,我们的store.js 将看起来像以下代码。

import AsyncStorage from '@react-native-async-storage/async-storage';
import { persistStore, persistReducer } from 'redux-persist'

import todoReducer from './reducers';
import { createStore } from 'redux'
import storage from 'redux-persist/lib/storage' 

const persistConfig = {
  key: 'root',
  storage: AsyncStorage,
}

const persistedReducer = persistReducer(persistConfig, todoReducer)

export const store = createStore(persistedReducer)
export const persistor = persistStore(store)

然后,我们通过导入PersistGate 来更新App.js ,并将应用包裹在其中。

import * as React from 'react';
import { Text } from 'react-native';
import { PersistGate } from 'redux-persist/integration/react'
import MyTodo from './Todo';


import {store, persistor} from './redux/store';
import { Provider } from 'react-redux';

const App = () => {
  return (
    <Provider store={store}>
    <PersistGate loading={<Text>Loading...</Text>} persistor={persistor}>
      <MyTodo/>
    </PersistGate>
    </Provider>
  );
}

export default App;

Redux Persist为我们在AsyncStorage 中持久化了Redux商店。即使我们离开应用程序,以后再回来,它也会从AsyncStorage 中获取数据,并用它来初始化Redux商店。

总结

在这篇文章中,我们回顾了什么是Redux Persist以及如何在React Native应用中设置它。当你需要在没有数据库的情况下持久化登录会话和其他信息时,Redux Persist很有帮助。它通过允许你的用户退出并返回到你的应用程序而不丢失他们的数据,大大改善了用户体验。我希望你喜欢这篇文章,如果你有任何问题,请务必留下评论。编码愉快!