为什么我的 React Native FlatList 上有相同值的键?

Why there is keys with same value on my React Native FlatList?

我并不总是收到有关具有相同值的键的警告,但它经常出现。大多数情况下它发生在第一次搜索时。

这是我的代码:

const ITEMS_PER_PAGE = 5 

export default class SearchForm extends Component {

    state = {
        allStates: [],
        states: [],
        page: 1,
        displayStatesList: false,
    }

    componentDidMount = async () => {
        await fetch('https://servicodados.ibge.gov.br/api/v1/localidades/estados', {
            method: 'GET',
            headers: {
                Accept: 'application/json',
                'Content-Type': 'application/json',
            },
        })
        .then(res => res.json())
        .then(res => this.setState({ allStates: res, states: res.slice(0, ITEMS_PER_PAGE -1) })) 
    }

    updateSearch = search => {
        let { allStates } = this.state
        this.setState({ 
            states: allStates.filter(res => res.nome.includes(search)),
            displayStatesList: true,
            search: search,
        })       
    }

    loadMore = () => {
        const { page, states, allStates, search } = this.state
        const start = page*ITEMS_PER_PAGE
        const end = (page+1)*ITEMS_PER_PAGE-1
        const newData = allStates.slice(start, end).filter(res => res.nome.includes(search))
        console.log(allStates.length)
        this.setState({
            states: [...states, ...newData],
            page: page + 1,
        })
    }

    selectItem = (nome) => {
        console.log('press', nome)
        this.setState({
            search: nome,
            displayStatesList: false,
        })
    }

    renderItem = ({ item }) => {
        return (
            <View>
                <ListItem
                    title={item.nome}  
                    onPress={() => this.selectItem(item.nome)}                  
                />
            </View>
        );
    }

    render() {

        const {
            search,
            states,
            displayStatesList,
        } = this.state

        return (
            <View style={styles.container}>
                <SearchBar
                    placeholder="Type Here..."
                    onChangeText={this.updateSearch}
                    value={search}
                    lightTheme
                />
                <View style={styles.listContainer}>
                    {displayStatesList && <FlatList
                        data={states}
                        keyExtractor={item => item.id.toString()}
                        renderItem={this.renderItem}
                        onEndReached={this.loadMore}
                        onEndReachedThreshold={0.7}
                    />}    
                </View>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignSelf: 'stretch',
        backgroundColor: '#fff',
    },
    listContainer: {
        height: 200
    },
})

也许我正在做一些不被推荐的事情并且它导致了错误? 或者 .slice 不正确?

观察:如果API不工作,我可以放一个json文件进行测试。

尝试使用 this handy function 来确保您的对象数组中没有重复项。

loadMore 方法中添加新数据时,API 响应或您身边可能存在重复。

你可以尝试改变这个keyExtractor={(item,index)=> index.toString()}

并将其作为道具添加到 renderItem key={index} 的第一个组件。

这将确保为“Flatlist”中的每个项目提供的键是唯一的。