likes
comments
collection
share

如何在 React Native 中使用 FlatList 和 MobX

作者站长头像
站长
· 阅读数 47

如何在 React Native 中使用 FlatList 和 MobX

介绍

在开发 React Native 应用时,我们经常需要使用列表来展示数据。React Native 提供了一个高性能的滚动列表组件,叫做 FlatList,它可以展示大量的数据,并且只渲染当前可见的项目。

但是,如何管理和更新列表中的数据呢?这时候,我们就需要一个状态管理库来帮助我们。MobX 是一个简单、可扩展和强大的状态管理库,它可以让我们用最少的代码来管理和更新我们的应用状态,并且自动优化渲染效果。

在本文中,我们将介绍如何在 React Native 中使用 FlatList 和 MobX 来显示一个待办事项列表。我们将使用 MobX 的 observable 来存储和修改数据,使用 observer 来让组件响应数据的变化,以及使用一些技巧来解决一些常见的问题。

创建待办事项类和列表类

首先,我们需要创建一个待办事项的类,用来表示每个待办事项的数据结构。我们需要给每个待办事项一个 id,一个 title 和一个 done 属性,分别表示唯一标识、标题和完成状态。我们还需要给这个类一个 toggle 方法,用来切换完成状态。

为了让这个类变成 observable,也就是可以被 MobX 跟踪和响应的状态或值,我们需要使用 makeAutoObservable 这个函数来包装它。这个函数会自动把类中的属性和方法变成 observable 和 action。

import { makeAutoObservable } from "mobx";

// 创建一个待办事项的类
class Todo {
  id = Math.random();
  title = "";
  done = false;

  constructor(title) {
    makeAutoObservable(this);
    this.title = title;
  }

  toggle() {
    this.done = !this.done;
  }
}

接下来,我们需要创建一个待办事项列表的类,用来表示整个列表的数据结构。我们需要给这个类一个 todos 属性,用来存储所有的待办事项。我们还需要给这个类两个方法,分别是 add 和 remove,用来添加和删除待办事项。

同样地,为了让这个类变成 observable,我们也需要使用 makeAutoObservable 这个函数来包装它。

import { makeAutoObservable } from "mobx";

// 创建一个待办事项列表的类
class TodoList {
  todos = [];

  constructor() {
    makeAutoObservable(this);
  }

  add(todo) {
    this.todos.push(new Todo(todo));
  }

  remove(todo) {
    this.todos = this.todos.filter((t) => t.id !== todo.id);
  }
}

最后,我们需要创建一个待办事项列表的实例,用来作为我们应用的状态源。

import { makeAutoObservable } from "mobx";

// 创建一个待办事项列表的实例
const todoList = new TodoList();

创建输入组件

接下来,我们需要创建一个用于输入待办事项的组件。这个组件需要有一个文本输入框和一个按钮,用来输入标题和添加待办事项。

为了让这个组件能够响应数据的变化,我们需要使用 observer 这个函数来包装它。这个函数会把组件变成 reaction,也就是当 observable 发生变化时自动执行的副作用或计算。

在这个组件中,我们使用 React 的 useState 钩子来存储文本输入框的值,并且使用 onChangeText 属性来更新它。当用户点击按钮时,我们调用 todoList 的 add 方法来添加一个新的待办事项,并且清空文本输入框。

import React from "react";
import { View, Text, TextInput, Button } from "react-native";
import { observer } from "mobx-react";

// 创建一个用于输入待办事项的组件
const TodoInput = observer(() => {
  const [text, setText] = React.useState("");

  const handleAdd = () => {
    if (text.trim()) {
      todoList.add(text);
      setText("");
    }
  };

  return (
    <View style={{ flexDirection: "row", margin: 10 }}>
      <TextInput
        style={{ flex: 1, borderWidth: 1, borderColor: "gray", padding: 10 }}
        value={text}
        onChangeText={setText}
        placeholder="Enter a todo"
      />
      <Button title="Add" onPress={handleAdd} />
    </View>
  );
});

创建列表组件

接下来,我们需要创建一个用于显示待办事项列表的组件。这个组件需要使用 FlatList 来展示数据,并且提供一些操作按钮,用来切换完成状态和删除待办事项。

同样地,为了让这个组件能够响应数据的变化,我们也需要使用 observer 这个函数来包装它。

在这个组件中,我们使用 FlatList 的 data 属性来传入 todoList 的 todos 属性,用来表示列表的数据源。我们还需要使用 keyExtractor 属性来指定每个项目的唯一标识,以及使用 renderItem 属性来指定每个项目的渲染方式。

但是,这里有一个问题。由于 MobX 的数组是对象,而 FlatList 的 data 属性期望一个数组,所以我们不能直接传入 todoList.todos。我们需要用 toJS 或者 slice 来转换一下,或者用扩展运算符(…)来创建一个新的数组。这样才能让 FlatList 正常工作。

import React from "react";
import { View, Text, Button, FlatList } from "react-native";
import { observer } from "mobx-react";

// 创建一个用于显示待办事项列表的组件
const TodoList = observer(() => {
  return (
    <FlatList
      data={todoList.todos.slice()}
      keyExtractor={(item) => item.id.toString()}
      renderItem={({ item }) => <TodoItem todo={item} />}
    />
  );
});

创建项目组件

接下来,我们需要创建一个用于显示单个待办事项的组件。这个组件需要显示标题和完成状态,并且提供两个按钮,用来切换完成状态和删除待办事项。

同样地,为了让这个组件能够响应数据的变化,我们也需要使用 observer 这个函数来包装它。

在这个组件中,我们使用 Text 组件来显示标题,并且根据 done 属性来决定是否添加删除线。我们还使用 Button 组件来提供两个操作按钮,并且调用 todo 的 toggle 方法和 todoList 的 remove 方法来执行相应的操作。

import React from "react";
import { View, Text, Button } from "react-native";
import { observer } from "mobx-react";

// 创建一个用于显示单个待办事项的组件
const TodoItem = observer(({ todo }) => {
  return (
    <View style={{ flexDirection: "row", alignItems: "center", margin: 10 }}>
      <Text
        style={{
          flex: 1,
          textDecorationLine: todo.done ? "line-through" : "none",
        }}
      >
        {todo.title}
      </Text>
      <Button title={todo.done ? "Undo" : "Done"} onPress={() => todo.toggle()} />
      <Button title="Remove" onPress={() => todoList.remove(todo)} />
    </View>
  );
});

创建根组件

最后,我们需要创建一个根组件,用来包含输入和列表组件,并且导出为默认模块。

import React from "react";
import { View } from "react-native";

// 创建一个根组件,包含输入和列表组件
const App = () => {
  return (
    <View style={{ flex: 1 }}>
      <TodoInput />
      <TodoList />
    </View>
  );
};

export default App;

转载自:https://juejin.cn/post/7254811936289407035
评论
请登录