以下代码是初期写的代码,后来对代码进行优化,解决了初期的bug。完整的选择城市三级联动组件可以参考我的github项目中的代码,这是后期调试成功上传上去的React选择城市三级联动组件

<SelectArea allAreaInfo={allAreaInfo} province={province}
city={city} district={district}
cancel={this.closeModal} confirm={this.SelectAddress} />
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import rest from '../../lib/rest';const HEIGHT = 36;
export class Picker extends Component {constructor(props) {super(props);this.state = {selectedIndex: this.props.index};this.onScroll = this.onScroll.bind(this);this.resetPosition = this.resetPosition.bind(this);}componentDidMount() {this.refs.scroller.scrollTop = this.state.selectedIndex * HEIGHT;this.refs.scroller.addEventListener('touchstart', this.touchStart, false);this.refs.scroller.addEventListener('touchend', this.touchEnd, false);this.refs.scroller.addEventListener('mousedown', this.touchStart, false);this.refs.scroller.addEventListener('mouseup', this.touchEnd, false);}touchStart() {this.isTouchStart = true;}touchEnd() {this.isTouchStart = false;if (this.timer) clearTimeout(this.timer);this.timer = setTimeout(this.resetPosition, 100);}onScroll() {if (this.timer) clearTimeout(this.timer);this.timer = setTimeout(this.resetPosition, 100);}resetPosition() {let provinceList = [], cityList = [], districtList = [];const { type = '', allAreaInfo = [], callback = () => { } } = this.props;if (this.isTouchStart) return;const top = this.refs.scroller.scrollTop;const distance = top % HEIGHT;let target;if (distance > HEIGHT / 2) {target = top + HEIGHT - distance;this.refs.scroller.scrollTop = target;} else {target = top - distance;this.refs.scroller.scrollTop = target;}const selectedIndex = target / HEIGHT;this.setState({selectedIndex}, () => {callback(type, selectedIndex);});}render() {const { list = [] } = this.props;return (<div className="ul-area" onScroll={this.onScroll} ref="scroller"><ul><li></li>{list.map((item, index) => (<li key={index} className={`${index === this.state.selectedIndex && 'selected'}`}>{item}</li>))}<li></li></ul></div>)}
}class SelectArea extends Component {constructor(props) {super(props);this.state = {provinceList: [],cityList: [],districtList: [],provinceIndex: 0,cityIndex: 0,districtIndex: 0,showPicker: false};this.handleSelect = this.handleSelect.bind(this);}componentDidMount() {const { allAreaInfo = [], province = '', city = '', district = '' } = this.props;let provinceList = [], cityList = [], districtList = [], provinceIndex = 0, cityIndex = 0, districtIndex = 0;if (province) {provinceIndex = allAreaInfo.findIndex(item => item.name === province);cityIndex = allAreaInfo[provinceIndex].city.findIndex(item => item.name === city);districtIndex = allAreaInfo[provinceIndex].city[cityIndex].area.findIndex(item => item === (district || '其他'));this.setState({provinceIndex,cityIndex,districtIndex,showPicker: true});}allAreaInfo.forEach(item => provinceList.push(item.name));if (allAreaInfo[provinceIndex].city.length) {allAreaInfo[provinceIndex].city.forEach(item => cityList.push(item.name));}this.setState({provinceList,cityList,districtList: allAreaInfo[provinceIndex].city[cityIndex] && allAreaInfo[provinceIndex].city[cityIndex].area,showPicker: true});}handleSelect(type, index) {let provinceList = [], cityList = [], districtList = [];const { provinceIndex, cityIndex, districtIndex } = this.state;const { allAreaInfo = [] } = this.props;switch(type) {case 'province':allAreaInfo[index].city.forEach(item => cityList.push(item.name));this.setState({provinceIndex: index,cityList,districtList: allAreaInfo[index].city[0] && allAreaInfo[index].city[0].area});break;case 'city':this.setState({cityIndex: index,districtList: allAreaInfo[provinceIndex].city[index] && allAreaInfo[provinceIndex].city[index].area});break;case 'district':this.setState({districtIndex: index,districtList: allAreaInfo[provinceIndex].city[cityIndex].area});break;default:break;}}render() {const { allAreaInfo = [], cancel = () => {}, confirm = () => {} } = this.props;const { provinceList, cityList, districtList, provinceIndex, cityIndex, districtIndex } = this.state;return (<div id="select-area"><div className="col-xs-12 select-area" onClick={e => e.stopPropagation()}><div className="row border-bottom-grey"><div className="col-xs-6" onClick={cancel}>取消</div><div className="col-xs-6 text-right font-orange"onClick={confirm.bind(null, provinceIndex, cityIndex, districtIndex)}>确定</div></div>{this.state.showPicker && (<div className="row list"><Picker type="province" allAreaInfo={allAreaInfo} list={provinceList} index={this.state.provinceIndex} callback={this.handleSelect} /><Picker type="city" allAreaInfo={allAreaInfo} list={cityList} index={cityIndex} callback={this.handleSelect} /><Picker type="district" allAreaInfo={allAreaInfo} list={districtList} index={districtIndex} callback={this.handleSelect} /></div>)}</div></div>)}
}SelectArea.contextTypes = {router: PropTypes.object.isRequired
};
SelectArea.propTypes = {// test: PropTypes.string.isRequired,
};
export default connect(state => (state))(SelectArea);

使用React实现选择城市三级联动组件相关推荐

  1. vue城市三级联动组件 vue-area-linkage

    Install the pkg with npm: // v5之前的版本 npm i --save vue-area-linkage// v5及之后的版本 npm i --save vue-area- ...

  2. uniapp自定义picker城市多级联动组件

    uniapp自定义picker城市多级联动组件 支持多端--h5.app.微信小程序.支付宝小程序... 支持自定义配置picker插件级数 支持无限级 注意事项:插件传入数据格式为children树 ...

  3. picker封装 uniapp_uniapp自定义picker城市多级联动组件

    uniapp自定义picker城市多级联动组件 支持多端--h5.app.微信小程序.支付宝小程序... 支持自定义配置picker插件级数 支持无限级 注意事项:插件传入数据格式为children树 ...

  4. 收货地址的JavaScript城市三级联动【干货拿走不谢!>_<】

    城市三级联动 在我们网上购物时会有收货地址一栏让我们选择收货地址,当中有省.市.区等选择项,如下图: 在添加收货地址时我们会先选择省再选市最后选所在区,这些都是下拉列表式的选择,选择完成才会填写具体地 ...

  5. 【web前端性能优化】13.城市三级联动

    最近做项目遇到一个城市三级联动的前端问题,感觉一个城市三级联动如果引入一个jquery库,有点太重了,于是就在网上找到了原始的js写法,感觉还挺好用的就记录一下,如下图所示: pay.html < ...

  6. 城市三级联动数据及地区代码对照表

    城市三级联动数据 介绍 使用说明 数据说明 做前端需要城市选择,在网上找到了别人的数据,但是没台湾省.作为爱国中年码农,婶可忍叔不可忍.所以就查阅了[中华人民共和国民政部]的网站,根据最新行程区划生成 ...

  7. 台湾、香港、澳门的城市三级联动json

    台湾.香港.澳门的城市三级联动json =========== 台湾 ============ {"citys": [{"areas": [{"are ...

  8. 城市三级联动功能实现

    背景: 最近在进行商品购买流程的开发,需要用户填写自己的收货地址,为了保证地址的准确性,需要使用到全国城市的三级联动功能 其中可以有三个思路: 1.使用 js 直接加载城市信息: 2.自己建立数据库, ...

  9. iOS 开发 带区号的城市三级联动(xml解析)

    iOS 开发 带区号的城市三级联动(xml解析) demo下载地址: http://download.csdn.net/detail/qq_20176153/9514906

最新文章

  1. 2018-4-5 丘成桐---现代几何学与计算机科学---自我总结
  2. bzoj 1409 Password 矩阵快速幂+欧拉函数
  3. OpenGL着色器基础
  4. DDD - 聚合与聚合根_如何理解 Respository与DAO
  5. 宏EXPORT_SYMBOL在内核中的作用
  6. vim的基本使用方法
  7. 【机器学习】情侣、基友、渣男和狗-基于时空关联规则的影子账户挖掘
  8. 图形系统中的仿射变换
  9. java代码初体验_第一次Java 8体验
  10. Fedora 20 安装试用体验全程讲解
  11. [vue] 跟keep-alive有关的生命周期是哪些?描述下这些生命周期
  12. 详解CNN五大经典模型:Lenet,Alexnet,Googlenet,VGG,DRL
  13. chmod 用法示例
  14. J2EE Architecture(6)
  15. js复制功能的有效方法总结
  16. Ubuntu20装Nvidia驱动--中文显示乱码问题
  17. 《5G应用“扬帆”行动计划(2021-2023年)》征求意见稿发布
  18. linux内核 print,自定义linux内核调试print
  19. vue 后台系统中多页面标签
  20. 网络安全-靶机dvwa之sql注入Low到High详解(含代码分析)

热门文章

  1. 论文学习:CAC模型
  2. android契约类是什么_为什么需要社会契约
  3. 4G模块SIMCOM7100 LTE在ARM Linux下使用PPPD上网
  4. 嵌入式语音信号处理入门篇
  5. 京东一面:Nginx 禁止国外 IP 访问网站!
  6. 《认知觉醒》的读后感
  7. 大一上半学期基础C语言程序(四则运算,日期求天数,阶乘....)
  8. Foursquare数据集说明与免费下载
  9. 渗透测试实例,xampp靶机实验
  10. 盘点数学上那些毁三观的“不可能”定理