React Native:在搜索栏中键入重新呈现平面列表,并在每次输入时关闭键盘

sqyvllje  于 2023-10-22  发布在  React
关注(0)|答案(1)|浏览(117)

我在react native中有一个帖子列表,我在一个平面列表中渲染。在屏幕的顶部有一个搜索栏(React本地文件)。我遇到的问题是,每当我更新搜索栏中的内容时(每次按键),更新过滤器和重新呈现平面列表的操作都会关闭键盘,打断用户。

export function AnnouncementsScreen({ navigation }) {
    const { editMode, setEditMode, selectedPost, setSelectedPost, openDetailedView, openEditView } =
        useContext(AnnouncementsNavigatorContext)
    const [refreshing, setRefreshing] = useState(false)
    const dispatch = useAppDispatch()
    const { companyPosts, status } = useTypedSelector((state) => state.companyPosts)
    const { dark: isDark, colors } = useTheme()

    const [filter, setFilter] = useState<Filter>({
        ...filterInitialState,
    })

    const { sortedPosts } = useSortedCompanyPosts(filter)


    const renderItem = useCallback(({ item }: { item: CompanyPost }) => {
        return (
            <View style={{ marginBottom: 10 }} key={item.post_id}>
                <Post post={item} expanded={false} navigation={navigation} />
            </View>
        )
    }, [])

    

    return (
        <View style={styles.page}>
            <View style={[styles.header, { borderColor: colors.border, backgroundColor: colors.card }]}>
                <Searchbar
                    placeholder="Search posts"
                    onChangeText={(value) => setFilter({ ...filter, search: value })}
                    value={filter.search}
                    style={[styles.input, { backgroundColor: isDark ? colors.background : '#E0E0E0' }]}
                />
                <View style={styles.buttonGroup}>
                    <Button
                        content="All"
                        color={filter.important ? colors.card : colors.primary}
                        _content={{ color: !filter.important ? 'white' : colors.primary }}
                        _button={{
                            borderColor: colors.border,
                            borderWidth: 1,
                            borderTopRightRadius: 0,
                            borderBottomRightRadius: 0,
                        }}
                        onPress={() => {
                            filter.important &&
                                setFilter({
                                    ...filter,
                                    important: false,
                                })
                        }}
                    />
                    <Button
                        content="Important"
                        color={!filter.important ? colors.card : colors.primary}
                        _content={{ color: filter.important ? 'white' : colors.primary }}
                        _button={{
                            borderColor: colors.border,
                            borderWidth: 1,
                            borderTopLeftRadius: 0,
                            borderBottomLeftRadius: 0,
                            borderLeftWidth: 0,
                        }}
                        onPress={() => {
                            !filter.important &&
                                setFilter({
                                    ...filter,
                                    important: true,
                                })
                        }}
                    />
                </View>
            </View>

            <View style={styles.listContainer}>
                <FlatList
                    windowSize={3}
                    initialNumToRender={7}
                    refreshControl={<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />}
                    data={sortedPosts}
                    renderItem={renderItem}
                    style={styles.flatList}
                    ListEmptyComponent={<AnnouncementsEmptyState />}
                    keyExtractor={(item) => item.post_id.toString()}
                />
            </View>
        </View>
    )
}

我已经尝试了工作区一样,有一个临时的过滤器状态,更新真实的过滤器时,键盘关闭,我宁愿它更新真实的时间

f0brbegy

f0brbegy1#

我认为首先你需要在你的FlatList上添加一个keyExtractor,或者在你的渲染项目上添加一个每个项目都是唯一的关键 prop 。这将有助于重新呈现列表项(如果它们已经呈现)。
范例:

<FlatList
 keyExtractor={(item) => item.id.toString()}  <<<<<<<<< This Line needs to be added
 windowSize={3}
 initialNumToRender={7}
 refreshControl={<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />}
 data={sortedPosts}
 renderItem={renderItem}
 style={styles.flatList}
 ListEmptyComponent={<AnnouncementsEmptyState />}
 keyExtractor={(item) => item.post_id.toString()}
/>

我以前没有使用过React Native Paper,但我认为键盘 Flink 的问题在于你将状态保持在输入组件之外。我建议让输入跟踪它的状态,然后回调过滤器更新。我想这应该能解决你的问题。
范例:

export function AnnouncementsScreen({ navigation }) {
    const { editMode, setEditMode, selectedPost, setSelectedPost, openDetailedView, openEditView } =
        useContext(AnnouncementsNavigatorContext)
    const [refreshing, setRefreshing] = useState(false)
    const dispatch = useAppDispatch()
    const { companyPosts, status } = useTypedSelector((state) => state.companyPosts)
    const { dark: isDark, colors } = useTheme()

    const [filter, setFilter] = useState<Filter>({
        ...filterInitialState,
    })

    const { sortedPosts } = useSortedCompanyPosts(filter)


    const renderItem = useCallback(({ item }: { item: CompanyPost }) => {
        return (
            <View style={{ marginBottom: 10 }} key={item.post_id}>
                <Post post={item} expanded={false} navigation={navigation} />
            </View>
        )
    }, [])

    

    return (
        <View style={styles.page}>
            <View style={[styles.header, { borderColor: colors.border, backgroundColor: colors.card }]}>
                <Searchbar
                    placeholder="Search posts"
                    onChangeText={(value) => setFilter({ ...filter, search: value })}
                    defaultValue={filter.search}
                    style={[styles.input, { backgroundColor: isDark ? colors.background : '#E0E0E0' }]}
                />
                <View style={styles.buttonGroup}>
                    <Button
                        content="All"
                        color={filter.important ? colors.card : colors.primary}
                        _content={{ color: !filter.important ? 'white' : colors.primary }}
                        _button={{
                            borderColor: colors.border,
                            borderWidth: 1,
                            borderTopRightRadius: 0,
                            borderBottomRightRadius: 0,
                        }}
                        onPress={() => {
                            filter.important &&
                                setFilter({
                                    ...filter,
                                    important: false,
                                })
                        }}
                    />
                    <Button
                        content="Important"
                        color={!filter.important ? colors.card : colors.primary}
                        _content={{ color: filter.important ? 'white' : colors.primary }}
                        _button={{
                            borderColor: colors.border,
                            borderWidth: 1,
                            borderTopLeftRadius: 0,
                            borderBottomLeftRadius: 0,
                            borderLeftWidth: 0,
                        }}
                        onPress={() => {
                            !filter.important &&
                                setFilter({
                                    ...filter,
                                    important: true,
                                })
                        }}
                    />
                </View>
            </View>

            <View style={styles.listContainer}>
                <FlatList
keyExtractor={(item) => item.id.toString()}
                    windowSize={3}
                    initialNumToRender={7}
                    refreshControl={<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} />}
                    data={sortedPosts}
                    renderItem={renderItem}
                    style={styles.flatList}
                    ListEmptyComponent={<AnnouncementsEmptyState />}
                    keyExtractor={(item) => item.post_id.toString()}
                />
            </View>
        </View>
    )
}

基本上,唯一的变化是将文本输入上的value prop更改为defaultValue,该值仅应在其值被内部控制之后在mount上设置值。
希望能帮上忙。

相关问题