TextInput 不过滤 FlatList 项目
TextInput doesn't filter FlatList items
我正在使用 Typescript,出于某种原因,下面的函数给出了错误:Property 'title' doesn't exist on type 'never'
。如果我在 JS 中编写相同的函数,它不会给我错误,仅在 Typescript 中。我不知道为什么,但我的 TextInput 不过滤 FlatList 项目。
const searchFilter =(text) => {
if(text){
const newData = masterData.filter((item) => {
//the error appears in the next line below in 'item.title'
const itemData = item.title ? item.title.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setFilteredData(newData);
setSearch(text);
} else {
setFilteredData(masterData);
setSearch(text);
}
}
我的 FlatList 工作并显示来自 JSON 获取的数据。唯一的问题是当我开始输入 TextInput
时 FlatList 消失了。
完整代码如下:
const ManageCustomersScreen =(props: ManageCustomersScreen) =>{
//navigation
const backPage = () => props.navigation.navigate("Home");
const callCustomer = () => props.navigation.navigate("Customer");
const [filteredData, setFilteredData] = useState([]);
const [masterData, setMasterData] = useState([]);
const [search, setSearch] = useState('');
useEffect(() => {
fetchPosts();
return() => {
}
}, [])
const fetchPosts = () => {
const apiUrl = 'https://jsonplaceholder.typicode.com/users';
fetch(apiUrl)
.then((response) => response.json())
.then((responseJson) => {
setFilteredData(responseJson);
setMasterData(responseJson);
}).catch((error) => {
console.error(error);
})
}
const ItemView = ({item}) => {
return(
<View style={manageCustomersStyle.tableBody}>
<View style={manageCustomersStyle.customerCard}>
<TouchableOpacity
style={manageCustomersStyle.customerCardContent}
onPress={callCustomer}>
<View style={manageCustomersStyle.customerCardInfo}>
<Text style={manageCustomersStyle.customerCardInfoName}>{item.name}</Text>
<Text style={manageCustomersStyle.customerCardInfoId}>{item.id}</Text>
</View>
<Icon
name="angle-double-right"
size={40}
color="grey"
/>
</TouchableOpacity>
</View>
</View>
)
}
const searchFilter =(text) => {
if(text){
const newData = masterData.filter((item) => {
const itemData = item.title ? item.title.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setFilteredData(newData);
setSearch(text);
} else {
setFilteredData(masterData);
setSearch(text);
}
}
return(
<SafeAreaView style={manageCustomersStyle.safeAreaView}>
<Appbar.Header>
<Appbar.BackAction onPress={backPage} />
<Appbar.Content title ="Manage Customers" />
</Appbar.Header>
<View style={manageCustomersStyle.searchBarView}>
<Icon
name="search"
size={30}
color="grey"
style={manageCustomersStyle.searchBarIcon}/>
<TextInput
style={manageCustomersStyle.searchBar}
placeholder={'Search'}
value={search}
onChangeText={(text) => searchFilter(text)}/>
</View>
<FlatList
data={filteredData}
keyExtractor={(item, index) => index.toString()}
renderItem={ItemView}
/>
</SafeAreaView>
);
}
export default ManageCustomersScreen;
这些屏幕截图显示,当我开始输入 TextInput
时,FlatList
就消失了。
一般
Typescript 用于编写打字 javascript。目前,您只是在 Typescript 文件中编写 javascript 。您并没有真正使用 Typescript。
您将从阅读中受益匪浅:https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
针对这个具体问题
我将首先更改此行以实际包含类型数据:
const [masterData, setMasterData] = useState([]);
目前,Typescript 可以为 masterData
确定的最严格的类型是 any[]
,这很糟糕。您希望尽可能避免 any
,因为这意味着 Typescript 无法对此变量执行任何类型检查。
例如,如果标题是一个可选字符串,您可以这样写:
const [masterData, setMasterData] = useState<{ title?: string }[]>([]);
或者更好的是,您可以将其定义为一种类型:
interface MasterDataItem {
title?: string
}
然后像这样使用它:
const [masterData, setMasterData] = useState<MasterDataItem[]>([]);
在您编写的这段代码上item.name
<Text style={manageCustomersStyle.customerCardInfoName}>{item.name}</Text>
但是在函数 searchFilter
上你尝试比较 item.title
,看来你打错了它应该 item.name
而不是 item.title
我正在使用 Typescript,出于某种原因,下面的函数给出了错误:Property 'title' doesn't exist on type 'never'
。如果我在 JS 中编写相同的函数,它不会给我错误,仅在 Typescript 中。我不知道为什么,但我的 TextInput 不过滤 FlatList 项目。
const searchFilter =(text) => {
if(text){
const newData = masterData.filter((item) => {
//the error appears in the next line below in 'item.title'
const itemData = item.title ? item.title.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setFilteredData(newData);
setSearch(text);
} else {
setFilteredData(masterData);
setSearch(text);
}
}
我的 FlatList 工作并显示来自 JSON 获取的数据。唯一的问题是当我开始输入 TextInput
时 FlatList 消失了。
完整代码如下:
const ManageCustomersScreen =(props: ManageCustomersScreen) =>{
//navigation
const backPage = () => props.navigation.navigate("Home");
const callCustomer = () => props.navigation.navigate("Customer");
const [filteredData, setFilteredData] = useState([]);
const [masterData, setMasterData] = useState([]);
const [search, setSearch] = useState('');
useEffect(() => {
fetchPosts();
return() => {
}
}, [])
const fetchPosts = () => {
const apiUrl = 'https://jsonplaceholder.typicode.com/users';
fetch(apiUrl)
.then((response) => response.json())
.then((responseJson) => {
setFilteredData(responseJson);
setMasterData(responseJson);
}).catch((error) => {
console.error(error);
})
}
const ItemView = ({item}) => {
return(
<View style={manageCustomersStyle.tableBody}>
<View style={manageCustomersStyle.customerCard}>
<TouchableOpacity
style={manageCustomersStyle.customerCardContent}
onPress={callCustomer}>
<View style={manageCustomersStyle.customerCardInfo}>
<Text style={manageCustomersStyle.customerCardInfoName}>{item.name}</Text>
<Text style={manageCustomersStyle.customerCardInfoId}>{item.id}</Text>
</View>
<Icon
name="angle-double-right"
size={40}
color="grey"
/>
</TouchableOpacity>
</View>
</View>
)
}
const searchFilter =(text) => {
if(text){
const newData = masterData.filter((item) => {
const itemData = item.title ? item.title.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setFilteredData(newData);
setSearch(text);
} else {
setFilteredData(masterData);
setSearch(text);
}
}
return(
<SafeAreaView style={manageCustomersStyle.safeAreaView}>
<Appbar.Header>
<Appbar.BackAction onPress={backPage} />
<Appbar.Content title ="Manage Customers" />
</Appbar.Header>
<View style={manageCustomersStyle.searchBarView}>
<Icon
name="search"
size={30}
color="grey"
style={manageCustomersStyle.searchBarIcon}/>
<TextInput
style={manageCustomersStyle.searchBar}
placeholder={'Search'}
value={search}
onChangeText={(text) => searchFilter(text)}/>
</View>
<FlatList
data={filteredData}
keyExtractor={(item, index) => index.toString()}
renderItem={ItemView}
/>
</SafeAreaView>
);
}
export default ManageCustomersScreen;
这些屏幕截图显示,当我开始输入 TextInput
时,FlatList
就消失了。
一般
Typescript 用于编写打字 javascript。目前,您只是在 Typescript 文件中编写 javascript 。您并没有真正使用 Typescript。
您将从阅读中受益匪浅:https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
针对这个具体问题
我将首先更改此行以实际包含类型数据:
const [masterData, setMasterData] = useState([]);
目前,Typescript 可以为 masterData
确定的最严格的类型是 any[]
,这很糟糕。您希望尽可能避免 any
,因为这意味着 Typescript 无法对此变量执行任何类型检查。
例如,如果标题是一个可选字符串,您可以这样写:
const [masterData, setMasterData] = useState<{ title?: string }[]>([]);
或者更好的是,您可以将其定义为一种类型:
interface MasterDataItem {
title?: string
}
然后像这样使用它:
const [masterData, setMasterData] = useState<MasterDataItem[]>([]);
在您编写的这段代码上item.name
<Text style={manageCustomersStyle.customerCardInfoName}>{item.name}</Text>
但是在函数 searchFilter
上你尝试比较 item.title
,看来你打错了它应该 item.name
而不是 item.title