React Native API数据填充autocomplete搜索下拉框失效求助
问题:本地数组正常的自动补全搜索框,改用API数据后失效
我实现了一个自动补全下拉搜索框,用本地数组dataSource时功能正常,但换成API获取的artistData后就失效了。已经用FlatList验证过artistData确实有数据,求帮忙排查解决。
原正常代码(App.js)
const App = () => { const [dataSource] = useState(['apple', 'banana', 'cow', 'dex', 'zee', 'orange', 'air', 'bottle']) const [filtered, setFiltered] = useState(dataSource); const [searching, setSearching] = useState(false); const onSearch = (text) => { if (text) { setSearching(true) const temp = text.toLowerCase() const tempList = dataSource.filter(item => {if (item.match(temp))return item}) setFiltered(tempList) } else { setSearching(false) } } return ( <SafeAreaView style={styles.container}> <TextInput style={styles.textInput} placeholder="Search" placeholderTextColor='white' onChangeText={onSearch} /> { searching && <SearchDropDown dataSource={filtered} /> } </SafeAreaView> ) }
原SearchDropDown.js组件
const SearchDropDown = (props) => { const {dataSource} = props; return ( <View> { dataSource.map((item,index) => { return ( <View> <View key={index}> <Text style={{color: 'black'}}>{item}</Text> </View> </View> ) }) } </View> ) }
修改后代码(App.js)
const [artistData, setArtist] = useState([]); const [filtered, setFiltered] = useState(artistData); const [searching, setSearching] = useState(false); useEffect(() => { axios.get(serveURL) .then((response) => setArtist(response.data)) .catch(error => { console.log(error) }); }, []); const onSearch = (text) => { if (text) { setSearching(true) const temp = text.toLowerCase() const tempList = artistData.filter(item => {if (item.match(temp))return item}) setFiltered(tempList) } else { setSearching(false) } } return ( <SafeAreaView style={styles.container}> <TextInput style={styles.textInput} placeholder="Search" placeholderTextColor='white' onChangeText={onSearch} /> { searching && <SearchDropDown artistData={filtered} /> } </SafeAreaView> )
修改后的SearchDropDown.js组件
const SearchDropDown = (props) => { const {artistData} = props; return ( <View> { artistData.map((item,index) => { return ( <View> <View key={index}> <Text style={{color: 'black'}}>{item}</Text> </View> </View> ) }) } </View> ) }
验证数据用的FlatList代码
<FlatList data = {serveURL} listKey="artist-data" keyExtractor={item => item.id} renderItem={({item}) => { return ( <Text>{item.artist_name}</Text> ) }} />
问题排查与解决
核心问题1:API返回的是对象数组,不是字符串数组
从FlatList代码能看到,API返回的每个item是包含artist_name属性的对象,但你在过滤和渲染时,仍按字符串数组的逻辑处理:
- 调用
item.match(temp)会直接报错(对象没有match方法) - 渲染
{item}会显示[object Object],看不到实际内容
核心问题2:FlatList验证代码有笔误
你写的data = {serveURL}应该是data={artistData},不过你已验证数据存在,推测是输入时的失误。
修改方案
- 修正搜索过滤逻辑,针对对象属性处理
修改onSearch函数,针对item.artist_name做匹配,同时统一大小写避免匹配误差:
const onSearch = (text) => { if (text) { setSearching(true) const temp = text.toLowerCase() const tempList = artistData.filter(item => item.artist_name.toLowerCase().includes(temp) ) setFiltered(tempList) } else { setSearching(false) setFiltered([]) // 清空搜索时重置过滤结果 } }
- 修正组件渲染逻辑,显示对象的目标属性
修改SearchDropDown组件,渲染时读取item.artist_name:
const SearchDropDown = (props) => { const {artistData} = props; return ( <View> { artistData.map((item, index) => { return ( <View key={index}> <Text style={{color: 'black'}}>{item.artist_name}</Text> </View> ) }) } </View> ) }
- 可选优化:添加API加载状态
避免用户在数据加载完成前搜索导致无响应:
const [loading, setLoading] = useState(true); useEffect(() => { axios.get(serveURL) .then((response) => { setArtist(response.data) setLoading(false) }) .catch(error => { console.log(error) setLoading(false) }); }, []); // 渲染时给输入框添加加载状态提示 <TextInput style={styles.textInput} placeholder={loading ? "加载中..." : "Search"} placeholderTextColor='white' onChangeText={onSearch} disabled={loading} />
内容的提问来源于stack exchange,提问作者delle
相关产品推荐
相关产品推荐

