如何解决Expo 应用 ComponentDidMount 侦听器 didFocus 未触发
我有一个 expo 应用程序,它确实有效,但突然停止了 - 我不知道为什么,因为我没有在 listView.js 上更新任何内容。
当我删除 list.js 中的列表时,应用程序按预期返回到listsView.js,但侦听器不会触发并刷新视图(列表仍保留在屏幕上)。
谁能告诉我它什么时候没有触发 - 我曾尝试将它从 componentDidMount 移动到 componentDidUpdate 但这会在加载时导致循环直到出错。
我的目标是让 listView.js 在导航回它以刷新任何已删除列表的列表时重新加载。
这是不会触发listView.js的隔离代码
componentDidMount() {
console.log("didmount??")
const { navigation } = this.props;
this.focusListener = navigation.addListener("focus",() => {
console.log("refreshing list") //this does not trigger
this.getLists();
});
}
listsView.js
import React,{ Component} from 'react';
import { Text,Button,View,FlatList,TouchableOpacity,Modal,TextInput,ScrollView } from 'react-native';
import { globalStyles } from '../styles/global';
import * as SecureStore from 'expo-secure-store';
import { MaterialIcons } from '@expo/vector-icons';
import { Ionicons } from '@expo/vector-icons';
import { Formik,Field,Form } from 'formik';
export default class App extends Component {
constructor() {
super();
this.state = {
data: [],loaded: true,error: null,token: "",modalVisible: false,};
}
componentDidMount() {
console.log("didmount??")
const { navigation } = this.props;
this.focusListener = navigation.addListener("focus",() => {
console.log("refreshing list") //this does not trigger
this.getLists();
});
}
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
goToList(id,name){
try{
this.props.navigation.navigate('List',{
JSON_ListView_Clicked_Item: id,listName: name
})
console.log(id)
} catch(error) {
console.log(error)
}
}
baseURL = 'https://www.mywebsite.com/api/auth';
showData = (data)=>{
this.setState({loaded:true,data:data});
}
badStuff = (err) => {
this.setState({loaded: true,error: err.message});
}
getLists = () => {
(async () => {
const token = await SecureStore.getItemAsync('token');
// Your fetch code
this.setState({loaded:false,error: null});
let url = this.baseURL + '/list';
let h = new Headers();
h.append('Authorization',`Bearer ${token}`);
h.append('Content-Type','application/json');
h.append('X-Requested-With','XMLHttpRequest');
let req = new Request(url,{
headers: h,method: 'GET'
});
fetch(req)
.then(response=>response.json())
.then(this.showData)
// .then(this.isMounted = true )
.catch(this.badStuff)
})();
}
componentDidMount() {
this.getLists()
}
render() {
return (
<View style={{flex:1}}>
<View style={globalStyles.container}>
<Modal visible={this.state.modalVisible}>
<View style={globalStyles.container}>
<MaterialIcons
name='close'
size={24}
color='orange'
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}
/>
<View style={globalStyles.centering}>
<View style={ globalStyles.logInScreen}>
<Text style={globalStyles.titleText}>Add New List</Text>
<Formik
initialValues={{ name: '' }}
onSubmit={values => {(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({loaded:false,error: null});
let url = 'https://www.mywebsite.com/api/auth/addList';
let h = new Headers();
h.append('Authorization',`Bearer ${token}`);
h.append('Content-Type','application/json');
h.append('X-Requested-With','XMLHttpRequest');
let b = JSON.stringify({
name: values.name,})
let req = new Request(url,{
headers: h,body: b,method: 'POST'
});
fetch(req)
.then(this.setModalVisible(false))
.then(this.getLists)
.then(response=>response.json())
.catch(this.badStuff)
})();}}
>
{({ handleChange,handleBlur,handleSubmit,values }) => (
<View>
<Text style={globalStyles.labelText}>Item:</Text>
<TextInput style={globalStyles.textInput}
onChangeText={handleChange('name')}
onBlur={handleBlur('name')}
value={values.email}
/>
<View style={globalStyles.buttons}>
<Button
title='Add New List'
onPress={handleSubmit}
color='orange'
/>
</View>
</View>
)}
</Formik>
</View>
</View>
</View>
</Modal>
{ !this.state.loaded && (
<Text>LOADING</Text>
)}
<View style={{ flexDirection: 'row',paddingLeft: 20}}>
<Ionicons
name="md-add-circle"
size={31} color="orange"
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}
/>
<Text style={{ alignSelf: 'center',paddingLeft: 5,color: 'white'}}>Add List</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<Text style={globalStyles.titleTextPadded}>Your Lists</Text>
</View>
{ this.state.error && (
<Text >{this.state.error}</Text>
)}
<View style={globalStyles.listNamesView}>
<FlatList contentContainerStyle={{ paddingBottom: 60}}
data={this.state.data}
renderItem={({ item }) => (
<TouchableOpacity onPress={() => this.goToList(item.lists.id,item.lists.name)}>
<Text style={globalStyles.listNameText}>
{ item.lists.name }
</Text>
</TouchableOpacity>
)}
keyExtractor = { (item) => item.lists.id.toString() }
/>
</View>
</View>
</View>
);
}
}
list.js
import React,{ Component,useState} from 'react';
import { Text,SafeAreaView,Alert } from 'react-native';
import * as SecureStore from 'expo-secure-store';
import { globalStyles } from '../styles/global';
import { CheckBox,Overlay } from 'react-native-elements'
import { Formik,Form } from 'formik';
import { MaterialIcons,Ionicons,Feather,AntDesign } from '@expo/vector-icons';
import { useNavigation } from '@react-navigation/native' // <-- import useNavigation hook
export default class App extends Component {
constructor() {
super();
this.state = {
data: [],userToken: "",};
}
showAlert = () => {
Alert.alert(
'DELETE','Are you sure you want to delete this list? You will not be able to recover it!',[
{text: 'Delete',onPress: () => this.deleteList(),style: 'destructive'},{text: 'Cancel',onPress: () => console.log('Cancel Pressed'),style: 'cancel'},],{ cancelable: false }
);
}
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
showData = (data)=>{
this.setState({loaded:true,data:data});
}
badStuff = (err) => {
this.setState({loaded: true,error: err.message});
}
getItems = () => {
(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({loaded:false,error: null});
this.setState({userToken: token});
let url = 'https://www.mywebsite.com/api/auth/items';
let h = new Headers();
h.append('Authorization',`Bearer ${token}`);
h.append('Content-Type','application/json');
h.append('X-Requested-With','XMLHttpRequest');
let b = JSON.stringify({
list_id: this.props.navigation.state.params.JSON_ListView_Clicked_Item,})
let req = new Request(url,{
headers: h,method: 'POST'
});
return fetch(req)
.then(response=>response.json())
.then(this.showData)
.catch(this.badStuff)
})();
}
componentDidMount() {
this._mounted = true;
const { navigation } = this.props;
this.getItems()
}
goToFriends = (id) => {
try{
this.props.navigation.navigate('Friends',{
listID: id
})
console.log(id)
} catch(error) {
console.log(error)
}
}
updateStatus(itemID,itemStatus) {
this.setState({loaded:false,error: null});
let token = this.state.userToken;
let url = 'https://www.mywebsite.com/api/auth/itemCheck';
let h = new Headers();
h.append('Authorization','Bearer ' + token);
h.append('Content-Type','application/json');
h.append('X-Requested-With','XMLHttpRequest');
let b = JSON.stringify({
item_id: itemID,item_status: itemStatus,list_id: this.props.navigation.state.params.JSON_ListView_Clicked_Item,})
let req = new Request(url,{
headers: h,method: 'POST'
});
return fetch(req)
.then(response=>response.json())
.then(this.getItems)
.catch(this.badStuff)
}
clearChecked(itemID,error: null});
let token = this.state.userToken;
let url = 'https://www.mywebsite.com/api/auth/clearChecked';
let h = new Headers();
h.append('Authorization','XMLHttpRequest');
let b = JSON.stringify({
list_id: this.props.navigation.state.params.JSON_ListView_Clicked_Item,method: 'POST'
});
return fetch(req)
.then(response=>response.json())
.then(this.getItems)
.catch(this.badStuff)
}
deleteList(itemID,itemStatus) {
console.log ('DELETE DELETE');
this.setState({loaded:false,error: null});
let token = this.state.userToken;
let url = 'https://www.mywebsite.com/api/auth/deleteList';
let h = new Headers();
h.append('Authorization',method: 'POST'
});
return fetch(req)
.then(response=>response.json())
.then(this.goToLists)
.catch(this.badStuff)
}
goToLists = () => {
this.props.navigation.navigate('ListsView');
}
render() {
return (
<SafeAreaView style={globalStyles.container}>
<Modal
visible={this.state.modalVisible}>
<View style={globalStyles.container}>
<MaterialIcons
name='close'
size={24}
color='orange'
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}
/>
<View style={globalStyles.centering}>
<View style={ globalStyles.logInScreen}>
<Text style={globalStyles.titleText}>Add Item</Text>
<Formik
initialValues={{ item: '' }}
onSubmit={values => {(async () => {
const token = await SecureStore.getItemAsync('token');
this.setState({loaded:false,error: null});
let url = 'https://www.myWebsite.com/api/auth/addItem';
let h = new Headers();
h.append('Authorization',`Bearer ${token}`);
h.append('Content-Type','application/json');
h.append('X-Requested-With','XMLHttpRequest');
let b = JSON.stringify({
item: values.item,})
let req = new Request(url,{
headers: h,method: 'POST'
});
fetch(req)
.then(this.setModalVisible(false))
.then(this.getItems)
.then(response=>response.json())
.catch(this.badStuff)
})();}}
>
{({ handleChange,values }) => (
<View>
<Text style={globalStyles.labelText}>Item:</Text>
<TextInput style={globalStyles.textInput}
onChangeText={handleChange('item')}
onBlur={handleBlur('item')}
value={values.email}
/>
<View style={globalStyles.buttons}>
<Button
title='Add Item'
onPress={handleSubmit}
color='orange'
/>
</View>
</View>
)}
</Formik>
</View>
</View>
</View>
</Modal>
{ !this.state.loaded && (
<Text></Text>
)}
<View style={{ flexDirection: 'row',paddingLeft: 20,paddingTop: 10,}}>
<Ionicons
name="md-add-circle"
size={31} color="orange"
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}}
/>
<Text style={{ alignSelf: 'center',color: 'white'}}>Add Item</Text>
<Feather
name="check-square"
size={31}
color="orange"
style={{ paddingLeft: 20,}}
onPress={() => {
this.clearChecked();
}}
/>
<Text style={{ alignSelf: 'center',color: 'white'}}>Clear</Text>
<Ionicons
name="ios-person-add"
size={31}
color="orange"
style={{ paddingLeft: 20,}}
onPress={() => {
this.goToFriends(this.props.navigation.state.params.JSON_ListView_Clicked_Item);
}}
/>
<Text style={{ alignSelf: 'center',color: 'white'}}>Friend</Text>
<AntDesign
name="delete"
size={31}
color="orange"
style={{ paddingLeft: 20,}}
onPress={() => {
this.showAlert();
}}
/>
<Text style={{ alignSelf: 'center',color: 'white'}}>Delete</Text>
</View>
<View style={{ flexDirection: 'row' }}>
<Text style={ globalStyles.titleTextPadded}>{ this.props.navigation.state.params.listName}</Text>
</View>
{ this.state.error && (
<Text >{this.state.error}</Text>
)}
<View>
<FlatList contentContainerStyle={{ paddingBottom: 100}}
data={this.state.data}
extraData={this.state}
renderItem={({ item }) => (
<TouchableOpacity>
<CheckBox style={globalStyles.listItem}
title={ item.item }
checked = { Boolean(Number(item.status))}
value={this.state.checked}
onPress={() => this.updateStatus(item.id,item.status)}
/>
</TouchableOpacity>
)}
keyExtractor = { (item) => item.id.toString() }
/>
</View>
</SafeAreaView>
);
}
}
更新: 我没有注意到我的第一个错误——我有 2 个 componentWillMount,第二个覆盖了第一个。 我现在已经删除了第二个并更新了第一个:
componentDidMount() {
const { navigation } = this.props;
console.log("didmount??")
this.focusListener = navigation.addListener("didFocus",() => {
console.log("refreshing list")
this.getLists();
});
}
当我删除一个列表并返回到listsView.js时,这现在按预期工作,但是当我登录并且listView.js第一次“命中”时,它现在不会加载列表!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。