LazyCascader.jsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { Cascader } from 'antd'
  2. import React, { forwardRef, useEffect } from 'react'
  3. import { connect } from 'umi'
  4. import styles from './index.less'
  5. const CLazyCascader = props => {
  6. const { refinstance, options, dispatch, onChange, changeOnSelect = false, ...resetProps } = props
  7. useEffect(() => {
  8. if (!options.length) {
  9. dispatch({
  10. type: 'district/fetch'
  11. })
  12. }
  13. }, [])
  14. const triggerChange = (value, local = '') => {
  15. if (onChange) {
  16. onChange(value, local)
  17. }
  18. }
  19. const handleOnChange = (value, selectedOptions) => {
  20. const local = selectedOptions.reduce((prev, curr) => {
  21. return `${prev}${prev ? ',' : ''}${curr.name}`
  22. }, '')
  23. triggerChange(value, local)
  24. }
  25. const loadData = selectedOptions => {
  26. const targetOption = selectedOptions[selectedOptions.length - 1]
  27. targetOption.loading = true
  28. // load options lazily
  29. dispatch({
  30. type: 'district/fetch',
  31. payload: { parentId: targetOption.id, level: targetOption.level }
  32. })
  33. }
  34. return (
  35. <div className={styles.cascader}>
  36. <Cascader
  37. getPopupContainer={triggerNode => triggerNode.parentNode}
  38. placeholder="省/市/区"
  39. options={options}
  40. ref={refinstance}
  41. onChange={handleOnChange}
  42. loadData={loadData}
  43. fieldNames={{ label: 'name', value: 'id' }}
  44. changeOnSelect={changeOnSelect}
  45. {...resetProps}
  46. />
  47. </div>
  48. )
  49. }
  50. const LazyCascader = connect(({ district }) => ({
  51. options: district.data
  52. }))(CLazyCascader)
  53. export default forwardRef((props, ref) => {
  54. return <LazyCascader {...props} refinstance={ref} />
  55. })