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"
    }
})
相关推荐
outstanding木槿28 分钟前
JS中for循环里的ajax请求不数据
前端·javascript·react.js·ajax
zhenryx4 小时前
微涉全栈(react,axios,node,mysql)
前端·mysql·react.js
六卿13 小时前
react防止页面崩溃
前端·react.js·前端框架
z千鑫13 小时前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js
小白学前端66615 小时前
React Router 深入指南:从入门到进阶
前端·react.js·react
outstanding木槿15 小时前
react+antd的Table组件编辑单元格
前端·javascript·react.js·前端框架
等一场春雨16 小时前
springboot 3 websocket react 系统提示,选手实时数据更新监控
spring boot·websocket·react.js
风无雨17 小时前
react杂乱笔记(一)
前端·笔记·react.js
北海天空17 小时前
reactHooks到底钩到了什么?
前端·react.js
飞翔的渴望17 小时前
react18与react17有哪些区别
前端·javascript·react.js