Rn实现省市区三级联动

省市区三级联动选择是个很频繁的需求,但是查看了市面上很多插件不是太老不维护就是不满足需求,就试着实现一个

这个功能无任何依赖插件

功能略简单,但能实现需求

核心代码也尽力控制在了60行左右
pca-code.json树型数据来源 Administrative-divisions-of-China

下面只贴了省市区选择的功能,全部代码可参考github area分支

js 复制代码
import { useState, useEffect } from 'react'
import { View, StyleSheet, FlatList, Text, TouchableOpacity } from 'react-native'
import pcaCode from "../assets/pca-code.json"

export default () => {
    const [selected, setSelected] = useState([]) //选择过的省市区
    const [options, setOptions] = useState([pcaCode]) //每一级的数据
    const [level, setLevel] = useState(0) // 当前展示第几级

    useEffect(() => {
        console.log(selected)
    }, [selected])

    const renderItem = ({ item }) => (
        <TouchableOpacity style={styles.option} onPress={() => activeItem(item)}>
            <Text style={[styles.option_text, isActive(item.code) && styles.option_text_active]}>{item.name}</Text>
            {isActive(item.code) && <View style={styles.option_icon} />}
        </TouchableOpacity >
    )

    const isActive = (code) => selected.some(item => item.code == code)

    const activeItem = (item) => {
        setSelected((prev) => {
            const newSelected = [...prev]
            newSelected[level] = { code: item.code, name: item.name }
            return newSelected.slice(0, level + 1)
        })
        if (level < 2) {
            const nextLevel = level + 1
            setLevel(nextLevel)
            setOptions((prev) => {
                const nextOptions = [...prev]
                nextOptions[nextLevel] = item.children
                return nextOptions
            })
        }
    }

    const PanelTab = () => {
        const tabs = selected.length < 3 ? selected.concat({ name: "请选择" }) : selected
        return (
            <View style={styles.tab}>
                {tabs.map((item, index) => {
                    return (
                        <View style={styles.tab_item} key={index}>
                            <TouchableOpacity onPress={() => setLevel(index)}>
                                <Text style={item.code ? styles.tab_item_text : styles.tab_item_text_gray}>
                                    {item.name}
                                </Text>
                            </TouchableOpacity>
                            {level == index && <View style={styles.tab_item_line} />}
                        </View>
                    )
                })}
            </View>
        )
    }
    return (
        <>
            <PanelTab />
            <FlatList style={styles.flat} data={options[level]} renderItem={renderItem} keyExtractor={item => item.code} />
        </>
    )
}

const styles = StyleSheet.create({
    flat: {
        height: 500,
    },
    option: {
        height: 40,
        paddingRight: 15,
        flexDirection: "row",
        alignItems: "center",
        justifyContent: "space-between",
    },
    option_text: {
        fontSize: 14
    },
    option_text_active: {
        color: "#409eff",
        fontWeight: 'bold',
    },
    option_icon: {
        width: 6,
        height: 10,
        borderBottomWidth: 2,
        borderBottomColor: "#409eff",
        borderRightWidth: 2,
        borderRightColor: "#409eff",
        transform: "rotate(45deg)"
    },
    tab: {
        flexDirection: "row",
        marginBottom: 10,
    },
    tab_item: {
        position: "relative",
        marginRight: 15,
    },
    tab_item_text: {
        fontSize: 14,
        fontWeight: 'bold',
        paddingBottom: 10,
    },
    tab_item_text_gray: {
        fontSize: 14,
        color: "gray",
        paddingBottom: 10,
    },
    tab_item_line: {
        position: "absolute",
        bottom: 0,
        left: 0,
        width: "100%",
        height: 3,
        borderRadius: 5,
        backgroundColor: "#409eff"
    }
})
相关推荐
jin12332222 分钟前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_9209317041 分钟前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪1 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
橙露2 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
2501_920931702 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...2 小时前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
打小就很皮...2 小时前
React 19 + Vite 6 + SWC 构建优化实践
前端·react.js·vite·swc
Highcharts.js2 小时前
使用Highcharts与React集成 官网文档使用说明
前端·react.js·前端框架·react·highcharts·官方文档
摘星编程4 小时前
OpenHarmony + RN:Stack堆栈导航转场
react native·react.js·harmonyos
摘星编程5 小时前
OpenHarmony环境下React Native:Tooltip自动定位
javascript·react native·react.js