react+antd 学年组件封装

SchoolYear.tsx

/*
  学年组件:
    1、使用时传入onChange事件,形如:<SchoolYear onChange={onSchoolYearChange} />
    2、默认为选中当前学年,如要不需要,设置 isSelected={false}
*/
import React, { useState, useEffect } from 'react'
import { Select } from 'antd'
import { useFetchState } from '@/utils/hooks'

import { getSchoolYearOptions } from '@/services/select'

interface OptionType {
  id: number
  name: string
}

interface SchoolYearProps {
  onChange?: (value: any) => void
  isSelected?: boolean
  isAllowClear?: boolean // 如果要支持清除,就传入 isAllowClear
  options?: Array<object> // 如果传入了学年options,组件内就不请求数据了
}

const SchoolYear: React.FC<SchoolYearProps> = (Props: any) => {
  const { onChange, isSelected = true, isAllowClear = false, options = [] } = Props
  const [yearOption, setYearOption] = useFetchState([]) // 学年选项list
  const [initYear, setInitYear] = useState() // 默认选中学年

  // 格式化接口数据,用于下拉框回显
  const format = (options: any[]) =>
    options.map(({ name, id }: OptionType) => ({
      label: `${name}学年`,
      value: id
    }))

  const set = (options: any) => {
    setYearOption(format(options))
    if (isSelected) {
      const year = options.find((item: any) => item.isCheck).id
      setInitYear(year)
      onChange(year)
    }
  }

  // 获取学年options
  const fetchYearOptions = async () => {
    if (options.length) {
      // console.log(options, format(options))
      set(options)
    } else {
      try {
        const { success, data, msg } = await getSchoolYearOptions()
        if (success && data) {
          set(data)
          return data
        }
        throw new Error(msg)
      } catch (err) {
        return false
      }
    }
  }

  useEffect(() => {
    fetchYearOptions()
  }, [])

  return (
    <Select
      onChange={onChange}
      allowClear={isAllowClear}
      placeholder="请选择学年"
      showSearch
      options={yearOption}
      defaultValue={initYear}
      key={initYear}
    />
  )
}

export default SchoolYear

 

学年组件要求默认选中当前学年,处理起来分异步和同步两种情况。

 

使用:

  第一种情况:学年组件被异步加载

    columns:

    {
      title: '所属学年',
      dataIndex: 'projectYear',
      key: 'projectYear',
      renderFormItem: () => <SchoolYear onChange={onSchoolYearChange} options={yearOptions} />
    }

    

    效果:

      

 

  第二种情况:同步加载学年组件

            <Form.Item label="学年" name="projectYear" >
              <SchoolYear onChange={onChangeYear} />
            </Form.Item>

    这种情况则仅适用change事件将当前学年传递到父组件中即可

    

    效果:

      

 

 

注意:

  1、注意异步的数据,传递到组件时的先后顺序。如果学年组件是被异步渲染的,那么就需要在父组件中获取当前学年,同时可以将options传递到子组件,减少子组件中重复的请求

  2、通过change事件将当前学年绑定到父组件中

 

posted @ 2022-02-11 18:19  吴小明-  阅读(141)  评论(0编辑  收藏  举报