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