在 React Native Flatlist 中添加搜索栏没有响应
Adding Search Bar In React Native Flatlist Is not Responding
在我的 React Native 应用程序中,我希望能够搜索和显示歌曲,我尝试实现搜索功能,但 none 似乎可行。下面的代码只允许我输入一个字母,当我输入一个字母时,我的 android 设备键盘消失了,我的列表仍然存在(不会触发搜索)。
我需要帮助才能使搜索功能正常工作,以便在用户搜索歌曲时显示我搜索的歌曲。
这是我的播放器列表代码:
import React, { useEffect, useState } from 'react';
import {
SafeAreaView,
View,
FlatList,
ScrollView,
TouchableOpacity,
ActivityIndicator,
TextInput,
} from 'react-native';
import Sound from 'react-native-sound';
import { Avatar, Text } from '@ui-kitten/components';
import Ionicons from 'react-native-vector-icons/Ionicons';
import filter from 'lodash.filter';
import songs from '../../SongData';
import styles from './styles';
const SonglistScreen = () => {
const [isDisabled, setisDisabled] = useState(false);
const [loading, setLoading] = useState(false);
const [isPlayed, setIsPlayed] = useState(false);
const [data, setData] = useState([]);
const [query, setQuery] = useState('');
const [song, setSong] = useState([]);
const [fullData, setFullData] = useState([]);
useEffect(() => {
getData();
}, []);
const getData = () => {
const res = (songs);
setData(res);
setFullData(res);
};
.....//
......//
const renderItem = ({ item, index }) => (
<ScrollView style={{flex: 1}}>
<View style={styles.item}>
<Avatar
source={{ uri: item.picture }}
style={{ marginRight: 16 }}
size='giant'
/>
<Text style={styles.title} category='s1'> {item.title} </Text>
</View>
<Text
style={{
color: '#444',
fontSize: 11,
marginLeft: 112,
marginVertical: -20,
bottom: 27
}}
category='s1'
>{item.ArtistName}
</Text>
<Text
style={{
color: '#999',
marginLeft: 110,
marginVertical: -20,
top: 10
}}
category='s1'
>Genre: {item.genre}
</Text>
<View style={{flexDirection: 'row', left: '230%', bottom: '7%'}}>
<TouchableOpacity
onPress={()=>playSound(item, index)}
style={{padding: 10, top: 30, left: 30}}
>
<Ionicons name="play" color={isPlayed ? 'red' : '#555555'} size={22} />
</TouchableOpacity>
<TouchableOpacity
onPress={()=>stopSound(index)}
style={{padding: 10, top: 30, left: 20}}
>
<Ionicons name="stop" color="#555555" size={22} />
</TouchableOpacity>
</View>
</ScrollView>
);
const handleSearch = text => {
let newData = songs.filter(item =>{
const itemData = `${item.title.toUpperCase()}`;
const textData = text.toUpperCase();
if (text.length > 0) {
return itemData.indexOf(textData) > -1;
}
});
setData(newData);
setQuery(text);
};
const renderHeader = () => {
return (
<View
style={{
backgroundColor: '#fff',
padding: 10,
marginVertical: 10,
borderRadius: 20
}}
>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
value={query}
onChangeText={text => handleSearch(text)}
placeholder="Search songs"
style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
/>
</View>
)
};
const renderFooter = () => {
if (!loading) return null
return (
<View
style={{
paddingVertical: 15,
borderTopWidth: 1,
borderColor: '#CED0CE',
}}
>
<ActivityIndicator animating size='large' />
</View>
);
}
...../
...../
return (
<SafeAreaView style={styles.container}>
<FlatList
data={songs}
renderItem={renderItem}
keyExtractor={item => item.id}
ItemSeparatorComponent={renderSeparator}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
/>
</SafeAreaView>
);
}
这是我要搜索显示的数据
songdata.js:
const songs = [
{
id: 1,
title: 'Hero',
ArtistName: 'Bethany Dilon',
genre: 'pop',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.18169-9/16195530_10211997136709517_8578854309931959016_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=09cbfe&_nc_eui2=AeEvt5zlNj1bM87SMIgRXz8VjFbfh8f8mfyMVt-Hx_yZ_ISR6pzt6j1tOqssNCwDfnM&_nc_ohc=oQeQeYLPRz8AX_n81Yh&_nc_ht=scontent-los2-1.xx&oh=d87b3097c543a39067095bacfbeb004d&oe=609BF1DC',
url: require('../../assets/songs/Hero.mp3'),
},
{
id: 2,
title: 'Advertising URL',
ArtistName: 'Bethany Dilon',
genre: 'Soft Rock',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url:
'https://raw.githubusercontent.com/zmxv/react-native-sound-demo/master/advertising.mp3',
},
{
id: 3,
title: 'Stronger',
ArtistName: 'Bethany Dilon',
genre: 'Country',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: require('../../assets/songs/Stronger.mp3'),
},
{
id: 4,
title: 'Faded',
ArtistName: 'Luchee',
genre: 'Techno',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Faded.mp3',
},
{
id: 5,
title: 'Solo',
ArtistName: 'Solo Cosmos',
genre: 'Afrobeat',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Solo.mp3',
},
{
id: 6,
title: 'Death Bed',
ArtistName: 'Omowunmi feat Wizkid',
genre: 'Afrocentric',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/death%20bed.mp3',
},
{
id: 7,
title: 'Hero',
ArtistName: 'Bethany Dilon',
genre: 'pop',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.18169-9/16195530_10211997136709517_8578854309931959016_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=09cbfe&_nc_eui2=AeEvt5zlNj1bM87SMIgRXz8VjFbfh8f8mfyMVt-Hx_yZ_ISR6pzt6j1tOqssNCwDfnM&_nc_ohc=oQeQeYLPRz8AX_n81Yh&_nc_ht=scontent-los2-1.xx&oh=d87b3097c543a39067095bacfbeb004d&oe=609BF1DC',
url: require('../../assets/songs/Hero.mp3'),
},
{
id: 8,
title: 'Advertising URL',
ArtistName: 'Bethany Dilon',
genre: 'Soft Rock',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url:
'https://raw.githubusercontent.com/zmxv/react-native-sound-demo/master/advertising.mp3',
},
{
id: 9,
title: 'Stronger',
ArtistName: 'Bethany Dilon',
genre: 'Country',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: require('../../assets/songs/Stronger.mp3'),
},
{
id: 10,
title: 'Faded',
ArtistName: 'Luchee',
genre: 'Techno',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Faded.mp3',
},
{
id: 11,
title: 'Solo',
ArtistName: 'Solo Cosmos',
genre: 'Afrobeat',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Solo.mp3',
},
{
id: 12,
title: 'Death Bed',
ArtistName: 'Omowunmi feat Wizkid',
genre: 'Afrocentric',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/death%20bed.mp3',
},
];
export default songs;
所以,这里的事情是一切都在同一个组件内,当你 运行 一个 setData
或 setQuery
你更新整个组件,你的键盘被重置。
关于您的列表尚未更新,这似乎是您的代码中的一个小错字:
return (
<SafeAreaView style={styles.container}>
<FlatList
// data={songs} <-- here you should be using data
data={data} // something like this
renderItem={renderItem}
keyExtractor={item => item.id}
ItemSeparatorComponent={renderSeparator}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
/>
</SafeAreaView>
);
但是您还需要更新您的状态声明,这样您就不会从一个空列表开始,来自:
const [data, setData] = useState([]);
对此:
const [data, setData] = useState(songs);
好的,这应该可以解决列表中没有过滤器的问题,因为现在您将使用您在过滤器函数中设置的变量,但是当您更新整个组件时,每次文本更改时,键盘消失的问题会不断发生.
我认为这是一个很好的解决方案:
使用某种全局状态管理(例如:Context 或 Redux,您也可以使用 mobx 实现此解决方案),这样您就可以创建一个名为 <ListHeader />
的独立组件,并放置您的查询更新在那里更新全局状态的列表值,这不会导致您的组件完全重新加载,只是列表会更新并且您可以保持字段焦点,也许这对您来说是一个新概念所以我分享一个示例使用此处上下文:
工作示例:
https://codesandbox.io/s/contextexample-p28z5?file=/src/App.js
静态代码:
import React, { useContext, useState } from "react";
import { Text, View, FlatList, TextInput } from "react-native";
const data = [
{ name: "qweqwe" },
{ name: "aaaaaa" },
{ name: "eeeeeeeee" },
{ name: "4" }
];
// List Context and ListProvider can be togheter in the same file
const ListContext = React.createContext({
list: [],
setList: () => {}
});
const ListProvider = ({ children }) => {
const [list, setList] = useState(data);
return (
<ListContext.Provider value={{ list, setList }}>
{children}
</ListContext.Provider>
);
};
const Item = ({ item }) => {
return (
<View>
<Text>{item.name}</Text>
</View>
);
};
const Header = () => {
const [text, setText] = useState("");
const listContext = useContext(ListContext);
const updateQuery = (str) => {
listContext.setList(data.filter((d) => d.name.indexOf(str) > -1));
setText(str);
};
return (
<View>
<TextInput value={text} onChangeText={updateQuery} />
</View>
);
};
const ListScreen = () => {
return (
<ListContext.Consumer>
{(context) => (
<View style={{ flex: 1 }}>
<FlatList
data={context.list}
keyExtractor={(i) => i.name}
renderItem={({ item }) => <Item item={item} />}
ListHeaderComponent={Header}
/>
</View>
)}
</ListContext.Consumer>
);
};
const App = () => {
return (
<ListProvider>
<ListScreen />
</ListProvider>
);
};
export default App;
祝你的项目成功。
在我的 React Native 应用程序中,我希望能够搜索和显示歌曲,我尝试实现搜索功能,但 none 似乎可行。下面的代码只允许我输入一个字母,当我输入一个字母时,我的 android 设备键盘消失了,我的列表仍然存在(不会触发搜索)。
我需要帮助才能使搜索功能正常工作,以便在用户搜索歌曲时显示我搜索的歌曲。
这是我的播放器列表代码:
import React, { useEffect, useState } from 'react';
import {
SafeAreaView,
View,
FlatList,
ScrollView,
TouchableOpacity,
ActivityIndicator,
TextInput,
} from 'react-native';
import Sound from 'react-native-sound';
import { Avatar, Text } from '@ui-kitten/components';
import Ionicons from 'react-native-vector-icons/Ionicons';
import filter from 'lodash.filter';
import songs from '../../SongData';
import styles from './styles';
const SonglistScreen = () => {
const [isDisabled, setisDisabled] = useState(false);
const [loading, setLoading] = useState(false);
const [isPlayed, setIsPlayed] = useState(false);
const [data, setData] = useState([]);
const [query, setQuery] = useState('');
const [song, setSong] = useState([]);
const [fullData, setFullData] = useState([]);
useEffect(() => {
getData();
}, []);
const getData = () => {
const res = (songs);
setData(res);
setFullData(res);
};
.....//
......//
const renderItem = ({ item, index }) => (
<ScrollView style={{flex: 1}}>
<View style={styles.item}>
<Avatar
source={{ uri: item.picture }}
style={{ marginRight: 16 }}
size='giant'
/>
<Text style={styles.title} category='s1'> {item.title} </Text>
</View>
<Text
style={{
color: '#444',
fontSize: 11,
marginLeft: 112,
marginVertical: -20,
bottom: 27
}}
category='s1'
>{item.ArtistName}
</Text>
<Text
style={{
color: '#999',
marginLeft: 110,
marginVertical: -20,
top: 10
}}
category='s1'
>Genre: {item.genre}
</Text>
<View style={{flexDirection: 'row', left: '230%', bottom: '7%'}}>
<TouchableOpacity
onPress={()=>playSound(item, index)}
style={{padding: 10, top: 30, left: 30}}
>
<Ionicons name="play" color={isPlayed ? 'red' : '#555555'} size={22} />
</TouchableOpacity>
<TouchableOpacity
onPress={()=>stopSound(index)}
style={{padding: 10, top: 30, left: 20}}
>
<Ionicons name="stop" color="#555555" size={22} />
</TouchableOpacity>
</View>
</ScrollView>
);
const handleSearch = text => {
let newData = songs.filter(item =>{
const itemData = `${item.title.toUpperCase()}`;
const textData = text.toUpperCase();
if (text.length > 0) {
return itemData.indexOf(textData) > -1;
}
});
setData(newData);
setQuery(text);
};
const renderHeader = () => {
return (
<View
style={{
backgroundColor: '#fff',
padding: 10,
marginVertical: 10,
borderRadius: 20
}}
>
<TextInput
autoCapitalize="none"
autoCorrect={false}
clearButtonMode="always"
value={query}
onChangeText={text => handleSearch(text)}
placeholder="Search songs"
style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
/>
</View>
)
};
const renderFooter = () => {
if (!loading) return null
return (
<View
style={{
paddingVertical: 15,
borderTopWidth: 1,
borderColor: '#CED0CE',
}}
>
<ActivityIndicator animating size='large' />
</View>
);
}
...../
...../
return (
<SafeAreaView style={styles.container}>
<FlatList
data={songs}
renderItem={renderItem}
keyExtractor={item => item.id}
ItemSeparatorComponent={renderSeparator}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
/>
</SafeAreaView>
);
}
这是我要搜索显示的数据 songdata.js:
const songs = [
{
id: 1,
title: 'Hero',
ArtistName: 'Bethany Dilon',
genre: 'pop',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.18169-9/16195530_10211997136709517_8578854309931959016_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=09cbfe&_nc_eui2=AeEvt5zlNj1bM87SMIgRXz8VjFbfh8f8mfyMVt-Hx_yZ_ISR6pzt6j1tOqssNCwDfnM&_nc_ohc=oQeQeYLPRz8AX_n81Yh&_nc_ht=scontent-los2-1.xx&oh=d87b3097c543a39067095bacfbeb004d&oe=609BF1DC',
url: require('../../assets/songs/Hero.mp3'),
},
{
id: 2,
title: 'Advertising URL',
ArtistName: 'Bethany Dilon',
genre: 'Soft Rock',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url:
'https://raw.githubusercontent.com/zmxv/react-native-sound-demo/master/advertising.mp3',
},
{
id: 3,
title: 'Stronger',
ArtistName: 'Bethany Dilon',
genre: 'Country',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: require('../../assets/songs/Stronger.mp3'),
},
{
id: 4,
title: 'Faded',
ArtistName: 'Luchee',
genre: 'Techno',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Faded.mp3',
},
{
id: 5,
title: 'Solo',
ArtistName: 'Solo Cosmos',
genre: 'Afrobeat',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Solo.mp3',
},
{
id: 6,
title: 'Death Bed',
ArtistName: 'Omowunmi feat Wizkid',
genre: 'Afrocentric',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/death%20bed.mp3',
},
{
id: 7,
title: 'Hero',
ArtistName: 'Bethany Dilon',
genre: 'pop',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.18169-9/16195530_10211997136709517_8578854309931959016_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=09cbfe&_nc_eui2=AeEvt5zlNj1bM87SMIgRXz8VjFbfh8f8mfyMVt-Hx_yZ_ISR6pzt6j1tOqssNCwDfnM&_nc_ohc=oQeQeYLPRz8AX_n81Yh&_nc_ht=scontent-los2-1.xx&oh=d87b3097c543a39067095bacfbeb004d&oe=609BF1DC',
url: require('../../assets/songs/Hero.mp3'),
},
{
id: 8,
title: 'Advertising URL',
ArtistName: 'Bethany Dilon',
genre: 'Soft Rock',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url:
'https://raw.githubusercontent.com/zmxv/react-native-sound-demo/master/advertising.mp3',
},
{
id: 9,
title: 'Stronger',
ArtistName: 'Bethany Dilon',
genre: 'Country',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: require('../../assets/songs/Stronger.mp3'),
},
{
id: 10,
title: 'Faded',
ArtistName: 'Luchee',
genre: 'Techno',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Faded.mp3',
},
{
id: 11,
title: 'Solo',
ArtistName: 'Solo Cosmos',
genre: 'Afrobeat',
isRequire: true,
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/Solo.mp3',
},
{
id: 12,
title: 'Death Bed',
ArtistName: 'Omowunmi feat Wizkid',
genre: 'Afrocentric',
picture: 'https://scontent-los2-1.xx.fbcdn.net/v/t1.6435-0/s640x640/169534769_1185223728571457_6192837830233317030_n.jpg?_nc_cat=101&ccb=1-3&_nc_sid=9267fe&_nc_eui2=AeH2splO8pf4k-atqrUeWWApKjkWnAsELXsqORacCwQte9doNY5rNtBrWht-o_CYYR4&_nc_ohc=plbZA_Pv91EAX_quQhG&_nc_ht=scontent-los2-1.xx&tp=7&oh=abec7b3bd8ddc13b6c3c0c510a33d8dc&oe=60997696',
url: 'https://github.com/ShivamJoker/sample-songs/raw/master/death%20bed.mp3',
},
];
export default songs;
所以,这里的事情是一切都在同一个组件内,当你 运行 一个 setData
或 setQuery
你更新整个组件,你的键盘被重置。
关于您的列表尚未更新,这似乎是您的代码中的一个小错字:
return (
<SafeAreaView style={styles.container}>
<FlatList
// data={songs} <-- here you should be using data
data={data} // something like this
renderItem={renderItem}
keyExtractor={item => item.id}
ItemSeparatorComponent={renderSeparator}
ListHeaderComponent={renderHeader}
ListFooterComponent={renderFooter}
/>
</SafeAreaView>
);
但是您还需要更新您的状态声明,这样您就不会从一个空列表开始,来自:
const [data, setData] = useState([]);
对此:
const [data, setData] = useState(songs);
好的,这应该可以解决列表中没有过滤器的问题,因为现在您将使用您在过滤器函数中设置的变量,但是当您更新整个组件时,每次文本更改时,键盘消失的问题会不断发生. 我认为这是一个很好的解决方案:
使用某种全局状态管理(例如:Context 或 Redux,您也可以使用 mobx 实现此解决方案),这样您就可以创建一个名为 <ListHeader />
的独立组件,并放置您的查询更新在那里更新全局状态的列表值,这不会导致您的组件完全重新加载,只是列表会更新并且您可以保持字段焦点,也许这对您来说是一个新概念所以我分享一个示例使用此处上下文:
工作示例:
https://codesandbox.io/s/contextexample-p28z5?file=/src/App.js
静态代码:
import React, { useContext, useState } from "react";
import { Text, View, FlatList, TextInput } from "react-native";
const data = [
{ name: "qweqwe" },
{ name: "aaaaaa" },
{ name: "eeeeeeeee" },
{ name: "4" }
];
// List Context and ListProvider can be togheter in the same file
const ListContext = React.createContext({
list: [],
setList: () => {}
});
const ListProvider = ({ children }) => {
const [list, setList] = useState(data);
return (
<ListContext.Provider value={{ list, setList }}>
{children}
</ListContext.Provider>
);
};
const Item = ({ item }) => {
return (
<View>
<Text>{item.name}</Text>
</View>
);
};
const Header = () => {
const [text, setText] = useState("");
const listContext = useContext(ListContext);
const updateQuery = (str) => {
listContext.setList(data.filter((d) => d.name.indexOf(str) > -1));
setText(str);
};
return (
<View>
<TextInput value={text} onChangeText={updateQuery} />
</View>
);
};
const ListScreen = () => {
return (
<ListContext.Consumer>
{(context) => (
<View style={{ flex: 1 }}>
<FlatList
data={context.list}
keyExtractor={(i) => i.name}
renderItem={({ item }) => <Item item={item} />}
ListHeaderComponent={Header}
/>
</View>
)}
</ListContext.Consumer>
);
};
const App = () => {
return (
<ListProvider>
<ListScreen />
</ListProvider>
);
};
export default App;
祝你的项目成功。