反应本机导航 - 更新屏幕中 add/update/delete 项的列表
react native navigation - update list in screen on add/update/delete items
我正在使用 React Native 构建移动应用程序。我正在使用 react-native-navigation 库中的堆栈导航器。
堆栈有两个屏幕,第一个屏幕 ItemsListScreen
显示带有添加按钮的项目列表,单击添加按钮导航到第二个屏幕 AddItemScreen
,其中显示项目的一些输入一个保存按钮。单击保存按钮将导航回列表屏幕。
项目当前保存在本地 SQLite 数据库中,但将来会保存在服务器上。
ItemsListScreen.js
import React, { useEffect, useState, useContext } from "react";
import { Button, Image, Platform, StyleSheet, View, TouchableOpacity } from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { Ionicons } from "@expo/vector-icons";
import DatabaseContext from "../db/DatabaseContext";
export default function ItemsListScreen({ navigation }) {
const db = useContext(DatabaseContext);
const [items, setItems] = useState([]);
useEffect(() => {
navigation.setOptions({
headerRight: () => {
return (
<TouchableOpacity activeOpacity={0.5} style={{ paddingRight: 10 }} onPress={() => navigation.navigate("AddItem")}>
<Ionicons name="md-add" size={30} />
</TouchableOpacity>
);
},
});
db.getItems().then((data) => {
setItems(data);
});
}, []);
return (
<View style={styles.container}>
<ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
{items.map((item, index) => (
<View key={index} style={styles.item}>
<Text style={styles.subSection}>{item.title}</Text>
</View>
))}
</ScrollView>
</View>
);
}
AddItemScreen.js
import React, { useState, useEffect, useContext } from "react";
import { StyleSheet, View, Dimensions, TextInput, ScrollView, TouchableOpacity, Picker, Switch } from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
import { Ionicons } from "@expo/vector-icons";
import DatabaseContext from "../db/DatabaseContext";
export default function AddItemScreen({ navigation }) {
const db = useContext(DatabaseContext);
const [item, setItem] = useState({
title: "",
description: "",
// more properties
});
const saveItem = () => {
db.saveItem(item);
navigation.navigate("ItemsList");
};
useEffect(() => {
navigation.setOptions({
headerRight: () => {
return (
<TouchableOpacity activeOpacity={0.5} style={{ paddingRight: 10 }} onPress={saveItem}>
<Ionicons name="md-save" size={30} />
</TouchableOpacity>
);
},
});
}, [item]);
return (
<View style={styles.scene}>
<ScrollView>
<Text style={styles.label}>Title</Text>
<TextInput style={styles.field} value={item.title} onChangeText={(text) => setItem((prevState) => ({ ...prevState, title: text }))} />
<Text style={styles.label}>Description</Text>
<TextInput style={styles.field} value={item.description} onChangeText={(text) => setItem((prevState) => ({ ...prevState, description: text }))} />
{/* more inputes */}
</ScrollView>
</View>
);
}
我的问题是 ItemsListScreen
上的列表在添加新项目时没有更新。我需要重新加载应用程序才能更新列表。
我试图从 ItemsListScreen 中的 useEffect 中删除第二个参数(空数组),它有效,但我认为这是一个糟糕的解决方案,因为它在每次重新渲染时不断从数据库中读取。
如何在用户导航回列表屏幕时刷新列表?我以为 useEffect
会在屏幕被激活时执行,但似乎不会。
您将通过向 ItemsListScreen.js 添加导航焦点侦听器来解决。用这种方式替换你的useEffet
useEffect(() => {
navigation.setOptions({
headerRight: () => {
return (
<TouchableOpacity activeOpacity={0.5} style={{ paddingRight: 10 }} onPress={() => navigation.navigate("AddItem")}>
<Ionicons name="md-add" size={30} />
</TouchableOpacity>
);
},
});
const unsubscribe = navigation.addListener('focus', () => {
db.getItems().then((data) => {
setItems(data);
});
});
return unsubscribe;
}, []);
我正在使用 React Native 构建移动应用程序。我正在使用 react-native-navigation 库中的堆栈导航器。
堆栈有两个屏幕,第一个屏幕 ItemsListScreen
显示带有添加按钮的项目列表,单击添加按钮导航到第二个屏幕 AddItemScreen
,其中显示项目的一些输入一个保存按钮。单击保存按钮将导航回列表屏幕。
项目当前保存在本地 SQLite 数据库中,但将来会保存在服务器上。
ItemsListScreen.js
import React, { useEffect, useState, useContext } from "react";
import { Button, Image, Platform, StyleSheet, View, TouchableOpacity } from "react-native";
import { ScrollView } from "react-native-gesture-handler";
import { Ionicons } from "@expo/vector-icons";
import DatabaseContext from "../db/DatabaseContext";
export default function ItemsListScreen({ navigation }) {
const db = useContext(DatabaseContext);
const [items, setItems] = useState([]);
useEffect(() => {
navigation.setOptions({
headerRight: () => {
return (
<TouchableOpacity activeOpacity={0.5} style={{ paddingRight: 10 }} onPress={() => navigation.navigate("AddItem")}>
<Ionicons name="md-add" size={30} />
</TouchableOpacity>
);
},
});
db.getItems().then((data) => {
setItems(data);
});
}, []);
return (
<View style={styles.container}>
<ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
{items.map((item, index) => (
<View key={index} style={styles.item}>
<Text style={styles.subSection}>{item.title}</Text>
</View>
))}
</ScrollView>
</View>
);
}
AddItemScreen.js
import React, { useState, useEffect, useContext } from "react";
import { StyleSheet, View, Dimensions, TextInput, ScrollView, TouchableOpacity, Picker, Switch } from "react-native";
import DateTimePicker from "@react-native-community/datetimepicker";
import { Ionicons } from "@expo/vector-icons";
import DatabaseContext from "../db/DatabaseContext";
export default function AddItemScreen({ navigation }) {
const db = useContext(DatabaseContext);
const [item, setItem] = useState({
title: "",
description: "",
// more properties
});
const saveItem = () => {
db.saveItem(item);
navigation.navigate("ItemsList");
};
useEffect(() => {
navigation.setOptions({
headerRight: () => {
return (
<TouchableOpacity activeOpacity={0.5} style={{ paddingRight: 10 }} onPress={saveItem}>
<Ionicons name="md-save" size={30} />
</TouchableOpacity>
);
},
});
}, [item]);
return (
<View style={styles.scene}>
<ScrollView>
<Text style={styles.label}>Title</Text>
<TextInput style={styles.field} value={item.title} onChangeText={(text) => setItem((prevState) => ({ ...prevState, title: text }))} />
<Text style={styles.label}>Description</Text>
<TextInput style={styles.field} value={item.description} onChangeText={(text) => setItem((prevState) => ({ ...prevState, description: text }))} />
{/* more inputes */}
</ScrollView>
</View>
);
}
我的问题是 ItemsListScreen
上的列表在添加新项目时没有更新。我需要重新加载应用程序才能更新列表。
我试图从 ItemsListScreen 中的 useEffect 中删除第二个参数(空数组),它有效,但我认为这是一个糟糕的解决方案,因为它在每次重新渲染时不断从数据库中读取。
如何在用户导航回列表屏幕时刷新列表?我以为 useEffect
会在屏幕被激活时执行,但似乎不会。
您将通过向 ItemsListScreen.js 添加导航焦点侦听器来解决。用这种方式替换你的useEffet
useEffect(() => {
navigation.setOptions({
headerRight: () => {
return (
<TouchableOpacity activeOpacity={0.5} style={{ paddingRight: 10 }} onPress={() => navigation.navigate("AddItem")}>
<Ionicons name="md-add" size={30} />
</TouchableOpacity>
);
},
});
const unsubscribe = navigation.addListener('focus', () => {
db.getItems().then((data) => {
setItems(data);
});
});
return unsubscribe;
}, []);