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"
    }
})
相关推荐
.生产的驴12 分钟前
React 路由权限跳转 Token判断 路由控制 登录状态控制
前端·javascript·react.js·ajax·前端框架·c#·ecmascript
2501_938769999 小时前
React Server Components 进阶:数据预取与缓存
前端·react.js·缓存
前端小咸鱼一条11 小时前
15. setState的更新是异步的吗
react.js
旧雨散尘15 小时前
【react】react初学6-第一个react应用-待办事项
前端·react.js·前端框架
Eiceblue17 小时前
React 前端实现 Word(Doc/Docx)转 HTML
前端·react.js·word
ideaout技术团队19 小时前
android集成react native组件踩坑笔记(Activity局部展示RN的组件)
android·javascript·笔记·react native·react.js
kaikaile199519 小时前
如何使用React和Redux构建现代化Web应用程序
前端·react.js·前端框架
前端小咸鱼一条19 小时前
13. React中为什么使用setState
前端·javascript·react.js
xw521 小时前
从一个按钮入门CSS in JS之styled-components
css·react.js
微风怎知我意21 小时前
前端框架入门怎么选?一篇搞懂 Vue、React、Angular 的取舍之道
vue.js·react.js·前端框架