我一直在谷歌上搜索了一段时间,但找不到一个明确的答案,我的问题是,我有一个搜索屏幕与文本输入和选择输入和按钮,所以我点击按钮后,输入文本和结果显示后,调用一个API。但问题是,当我导航到不同的屏幕,并返回到搜索屏幕的结果停留。我需要它是空的输入文本字段和结果。
我尝试了许多“解决方案”,但没有一个奏效。我使用了一个useEffect()钩子,它不起作用,试图将记录数组设置为空,但没有工作
以下是我的搜索屏幕代码:
import {
StyleSheet,
View,
ActivityIndicator,
FlatList,
Button,
} from 'react-native';
import React, { useState, useEffect } from 'react';
import AppTextInput from '../components/AppTextInput';
import Card from '../components/Card';
import colors from '../config/colors';
import axios from 'axios';
import { baseApiUrl, apikey } from '../api/config/apiLinks';
import AppPicker from '../components/AppPicker';
import AppText from '../components/AppText';
import { openBrowserAsync } from 'expo-web-browser';
const options = [
{ value: 'news', label: 'News' },
{ value: 'videos', label: 'Videos' },
{ value: 'documentaries', label: 'Documentaries' },
{ value: 'channels', label: 'Channels' },
];
export default function SearchScreen({ navigation }) {
const [selected, setSelected] = useState(options[0]);
const [input, setInput] = useState();
const [resultRecords, setResultRecords] = useState([]);
const [totalPages, setTotalPages] = useState();
const [currentPage, setCurrentPage] = useState(1);
const [errorMessage, setErrorMessage] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [attachEnd, setAttachEnd] = useState(false);
const url =
baseApiUrl +
'/search/search-get.php?' +
apikey +
'&category=' +
selected.value +
'&q=' +
input +
'&page=' +
currentPage +
'&count=15';
const loadSearchResult = () => {
setIsLoading(true);
console.log('selected: ', selected.value);
console.log('url: ', url);
axios
.get(url)
.then((response) => {
setErrorMessage(0);
console.log(response);
setTotalPages(response.data.totalPages);
if (attachEnd) {
setResultRecords([...resultRecords, ...response.data.data]);
} else {
setResultRecords(response.data.data);
}
setIsLoading(false);
setAttachEnd(false);
console.log('records: ', resultRecords);
})
.catch((error) => {
if (error.response.status == 404) {
setErrorMessage('Results not found!');
}
setIsLoading(false);
console.log(error.response);
});
};
const onInputChange = (text) => {
if (text != '') {
setInput(text);
console.log('onInputChange: ', input);
}
};
const renderLoader = () => {
return isLoading ? (
<View style={styles.loaderStyle}>
<ActivityIndicator size="large" color="#aaa" />
</View>
) : null;
};
//this useEffect execute the function only once
useEffect(() => {
setResultRecords([]);
setInput('');
}, [navigation]);
return (
<View style={styles.container}>
<View style={styles.innerContainer}>
<AppTextInput
placeholder="Search..."
icon="magnify"
onFieldChange={onInputChange}
/>
</View>
<View style={styles.innerContainer}>
<AppPicker
selectedItem={selected}
onSelectItem={(item) => setSelected(item)}
items={options}
icon="apps"
placeholder="Category"
/>
</View>
<View style={styles.button}>
<Button title="Search" onPress={loadSearchResult} />
</View>
<View style={styles.results}>
{errorMessage == '' && (
<FlatList
data={resultRecords}
keyExtractor={(records) => records.title}
renderItem={({ item }) => (
<Card
title={item.title}
feedName={item.feedName}
date={item.pubDate}
imageUrl={item.image}
onPress={() => {
console.log('selectedOnPress: ', selected);
console.log('browser: ', item.link);
if (selected.value == 'news') {
navigation.navigate(
'NewsDetailsScreen',
item
);
} else if (selected.value == 'videos') {
navigation.navigate(
'YoutubeVideoDetailsScreen',
item
);
} else if (
selected.value == 'documentaries'
) {
openBrowserAsync(item.link);
} else if (selected.value == 'channels') {
openBrowserAsync(item.link);
}
}}
/>
)}
ListFooterComponent={renderLoader}
/>
)}
{errorMessage != '' && (
<AppText style={styles.results}>{errorMessage}</AppText>
)}
</View>
</View>
);
}
const styles = StyleSheet.create({
loaderStyle: {
marginVertical: 16,
alignItems: 'center',
},
container: {
padding: 15,
paddingBottom: 50,
// backgroundColor: colors.light,
flexDirection: 'column',
width: '100%',
},
innerContainer: {
width: '100%',
},
button: {
width: '100%',
marginTop: 15,
marginBottom: 15,
},
results: {
marginTop: 15,
paddingBottom: 50,
textAlign: 'center',
},
});
3条答案
按热度按时间nqwrtyyt1#
您需要使用
useFocusEffect
代替useEffect
:我建议阅读文档https://reactnavigation.org/docs/navigation-lifecycle/
ldxq2e6h2#
您应该使用**
replace
**而不是navigate
。注意事项:
navigate
:将新路由推入堆栈。上一个路由将不会被卸载replace
:将用新路由替换以前的路由。acruukt93#
你也可以使用
Promise.prototype.finally
这样做: