《问题总结》frontpagesetting企业分类排序之后,修改下拉选项值,排序列表重新回到原始状态


问题描述

在做企业frontpagesetting的时候,有个分类列表,需要支持对分类进行排序,但是在对分类排序之后,然后修改下拉选项值,排序列表重新回到了原始状态

问题分析

在组件生命周期getDerivedStateFromProps方法中,比对props, state中的list数据,因为displayType是可变的,所以会判断 R.symmetricDifference不为空,从而导致重新赋值state的list值,造成排序被还原

解决方法

思路:

知道上面是因为排序之后在修改下拉选项值之后,导致的列表顺序还原,displayType是可变的。基于这个原因,不使用list来判断,而是使用itemIds单个的id数组,这样不管顺序怎么排列,和displayType的值怎么修改都不会造成顺序还原。

代码实现:

1、生命周期函数getDerivedStateFromProps中比对id数组,并赋值给state的itemIds

static getDerivedStateFromProps(props, state) {
    if (
      !R.isEmpty(
        R.symmetricDifference(
          R.pluck(props.draggableId, props.dataSource),
          state.itemIds
        )
      )
    ) {
      return {
        itemIds: R.pluck(props.draggableId, props.dataSource)
      }
    }
    return null
  }

2、渲染数据列表时候 ,通过遍历itemIds,根据id从dataSource中获取并显示相关filed字段

{this.state.itemIds.map((id, index) => {
                    const item = R.find(R.propEq(draggableId, id), dataSource)
                    return (
                      
                        {(provided2, snapshot2) => (
                          
{this.renderDraggableContent(item)}
)}
) })}

3、监听排序函数,将排序后的itemIds传递到父组件中

onDragEnd = result => {
    const { destination, source } = result
    const { onOrderChange } = this.props
    // dropped outside the list
    if (R.isNil(destination)) return
    // dropped in same position
    if (
      R.allPass([R.eqProps('droppableId'), R.eqProps('index')])(
        destination,
        source
      )
    ) {
      return
    }
    this.setState(
      prevState => ({
        itemIds: this.reorder(
          prevState.itemIds,
          source.index,
          destination.index
        )
      }),
      () => {
        onOrderChange(this.state.itemIds)
      }
    )
  }

  reorder = (list, startIndex, endIndex) => {
    const newOrder = R.insert(
      endIndex,
      list[startIndex],
      R.remove(startIndex, 1, list)
    )
    return newOrder
  }

4、父组件监听到排序函数重新表单赋值

handleOrderChange = newOrder => {
    this.props.form.setFieldsValue({
      order: newOrder
    })
  }


                
              
              {getFieldDecorator('order', {
                initialValue: corporateFrontpageCategoryList
                  .map(corpCat => corpCat.get('corporateCategoryNo'))
                  .toArray()
              })()}

5、selector中处理接口返回的controlSetting数据,在corporateCategoryList中添加列表所需要的name字段

export const getCorporateFrontpageCategoryList = createSelector(
  getCorporateCategoryList,
  controlSettingSelector,
  (corporateCategoryList, controlSetting) => {
    if (R.isNil(corporateCategoryList) || R.isNil(controlSetting)) {
      return List()
    }
    return controlSetting
      .get('corporateCategoryList')
      .map(frontpageCorpCat =>
        frontpageCorpCat.set(
          'name',
          corporateCategoryList
            .find(
              (corpCat, key, iter) =>
                corpCat.get('corporateCategoryNo') ===
                frontpageCorpCat.get('corporateCategoryNo')
            )
            .get('name')
        )
      )
  }
)

6、在getCorporateCategoryColumns中使用displayType.${corporateCategoryNo}.displayType形式给select赋值

数据格式 displayType: {CORPCATE10034: {…}, CORPCATE10091: {…}, CORPCATE10093

{
      title: i18n.t('corporateFrontpageSetting.label.imgStyle'),
      dataIndex: 'corporateCategory.displayType',
      key: 'displayType',
      render: ({ corporateCategoryNo, displayType }: Object, index: number) => {
        return getFieldDecorator(
          `displayType.${corporateCategoryNo}.displayType`,
          {
            initialValue: displayType
          }
        )(
          
        )
      }
    },
//删除列表行数据
{
      title: i18n.t('corporateFrontpageSetting.label.action'),
      dataIndex: 'corporateCategory.action',
      width: 100,
      key: 'action',
      render: (record: Object) => {
        const updatedFrontpageCorporateCategoryList = corporateCategoryList.filterNot(
          item => item.get('corporateCategoryNo') === record.corporateCategoryNo
        )
        return (
          
        )
      }
    }

7、最后请求保存接口的时候对数据做处理

解构formValues中除了order和displayType的数据,处理并组装corporateCategoryList数据,最后拼装并返回接口请求所需格式
corporateHome: {articleIds: Array(4), displayCorporateCategory: "CORPCATE10077"}
corporateCategoryList: (6) [{…}, {…}, {…}, {…}, {…}, {…}]

patchFormValues = formValues => {
    return {
      ...R.omit(['order', 'displayType'])(formValues),
      corporateCategoryList: R.map(
        corporateCategoryNo => ({
          corporateCategoryNo,
          displayType: R.path(
            ['displayType', corporateCategoryNo, 'displayType'],
            formValues
          )
        }),
        R.path(['order'])(formValues)
      )
    }
  }