I have developed a basic Search Bar component in my React Native project, and I would like to store the user’s search query in my parent element, and display this search query within the Search Bar. This is what I have so far:
Child Search Bar Component
import {Text, View, TextInput} from 'react-native'
import React from 'react'
const SearchBar = ({data, setData, setResult, filter, limit, value}) => {
const filterList = (search) => {
let filtered = data.filter((item) => item[filter].toLowerCase().includes(search.toLowerCase()))
if(limit) {
filtered = filtered.slice(0, limit)
}
setData(filtered)
setResult(search)
}
return (
<View className="mt-2 w-full h-10 px-2 bg-gray-300 border-2 border-black-200 focus:border-secondary flex flex-row items-center">
<TextInput className="flex-1 text-black font-psemibold bg-gray-300" value={value} onChangeText={(search) => filterList(search)} clearButtonMode='always'/>
</View>
)
}
export default SearchBar
Parent Component
import { Text, View, Button, ScrollView, TouchableWithoutFeedback } from 'react-native'
import React, { useState, useEffect } from 'react'
import Header from '../components/Header.jsx';
import { router, useFocusEffect } from 'expo-router';
import { get_users_friends } from '../services/profile.js'
import FormField from '../components/FormField.jsx';
import SearchBar from '../components/SearchBar.jsx'
const Trade = () => {
const [users, setUsers] = useState([])
const [filteredFriends, setFilteredFriends] = useState([])
const [formChoice, setFormChoice] = useState(null)
const [tradeName, setTradeName] = useState('')
const [otherUser, setOtherUser] = useState({
name: '',
_id: ''
})
const changeSearch = (value) => {
setOtherUser({ ...otherUser, name:value})
}
const changeFriends = (friends) => {
setFilteredFriends(friends)
}
const selectUser = (value) => {
setOtherUser({name:value.name, _id:value._id})
setFilteredFriends([])
}
async function setupData() {
//setup
}
useFocusEffect(
React.useCallback(() => {
setupData();
return () => {}
}, [])
)
return (
<>
<Header back={true}></Header>
<ScrollView className='flex-1 m-4'>
<SearchBar data={users} setData={changeFriends} setResult={changeSearch} filter={'name'} limit={5} value={otherUser.name}></SearchBar>
{Object.entries(filteredFriends).map(([key, value]) => (
<TouchableWithoutFeedback key={key} onPress={() => selectUser(value)}>
<View className="flex flex-row">
<View className="h-10 justify-center items-center flex flex-1 bg-secondary-100/30 border-b-2 border-l-2 border-r-2 border-secondary-100">
<Text className="text-black text-lg font-psemibold text-center">{value.name}</Text>
</View>
</View>
</TouchableWithoutFeedback>
))}
</ScrollView>
</>
)
}
export default Trade
The functionality is straightforward – I would like for users to be able to use the child “Search Bar” component to search and filter through a list of users, and upon selecting one of these users, have it displayed within the “Search Bar” TextInput component. The way I am doing this is by setting the value of both the “Search Bar” TextInput and “SearchBar” component itself to ‘otherUser.name’. This does work, however there is considerable glitching/lagging within the app, particularly when the user is typing fast. I think it might be setting it twice which is causing this issue, but I haven’t found another way do to this.
What is the correct approach I should be using?