antd react table扩展行(expandedRowRender)异步记载数据再渲染问题

因为数据关联的太多,然后table展示的时候,需要扩展行来展示数据,但是扩展行的数据关联的太多,所以没有必要一次性全部展示出来,可以按照需要,点击再进行请求数据,再进行渲染...

但是为了实现这个需求... 我花了好几天...... 崩溃了都...

ps:我写golang/php 的, 这前端,对着文档编程..有点苦逼...

官方文档: https://ant.design/components/table-cn/#Table

根据文档的写法,可利用两个东西,

onExpand

expandedRowRender

开始我将 扩展行写在 expandedRowRender里,里面异步请求数据,但是发现一直在请求数据,然后内存暴涨... 浏览器都卡住了.... 会报这个错误

Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method

看了react的生命周期,原来是一直 dispatch==> setState==> render ==> dispatch==> setState==> render

然后写在 onExpand里,但是一旦请求数据,点击别的行,所有行的数据变成一个了.....显然,这并不是我想要的

然后参考其他人的写法,改一下写法, 思路是:

  1. 首先,得设置expandedRowRenders 默认为true,不然不显示那个点击按钮
  2. onExpand是记录点击扩展行的,但是数据渲染应该还是放在 expandedRowRenders,所以,可以通过onExpand,然后把渲染的数据传给expandedRowRenders
  3. 将2里的数据放到 state里,一旦点击,扩展打开状态,请求数据,将数据实时返给子组件(我的扩展行放在子组件里)
const sstyle = {
  display:'none',
};

const expandedRowRenders = record => <p style={sstyle}>{record}</p>;

class dataList extends PureComponent {
    state = {
        expandVisible: {},
        expandedRowRenders,
        expandedData:{}, 
    }

    onExpandedRowRender = (expanded,record) => {
        const { dispatch } = this.props;

        if (expanded) {
          dispatch({
            type: 'data/list',
            listId: record.id,
          }).then((dataOneData) => {
            const res = {
              ...this.state.expandedData,
              [record.id]: dataOneData,
            };

            this.setState({
              expandVisible:{
                ...this.state.expandVisible,
                [record.id]: true,
              },
              subTabData:res,
              //注意,用key对应value的形式来标识每个扩展行的子组件,不然,一个请求,所有数据又变成一个了...访问的时候,根据key来访问
              expandedRowRenders: {
                ...this.state.expandedRowRenders,
                [record.id]:<Expand expandVisible expandRecord={record} dataonedata={res} />,
              },
            });
          });
        } else {
        // 当关闭扩展行的时候,仅仅把改行改成false,其他行不用改,不然导致的bug就是关闭了某一行,其他行数据都没了.....
          this.setState({expandVisible:{
              ...this.state.expandVisible,
              [record.id]: false,
            }});
        }
  };
}

  render() {
       return (
             <Table
                loading={loading}
                columns={columns}
                rowKey="id"
                dataSource={ownerdatalistdata}
                onExpand={this.onExpandedRowRender.bind(this)}
                expandedRowRender={(record) =>  this.state.expandVisible[record.id] === true ? this.state.expandedRowRenders[record.id] : true}
                pagination={false}
            />
       )
  }

export default connect(({ data }) => ({  
    dataOneData:data.dataOneData,
}))(dataList);

再写个 Expand组件

class expand extends PureComponent {
    const {
      visible, expandRecord, grouponedata,
    } = this.props;

    return (
        <span> {grouponedata[expandRecord.id]} </span>
    )
}

因为 请求被拆分出来了,所以得注意修改一下

model 文件

export default {
    state: {
        dataOneData: {},
    }
    effects: {
         * dataonedata({ payload ,dataId}, { call, put }) {
              yield put({ type: 'openLoading' });
              const response = yield call(dataOneData, payload,dataId);
              if (!response || response.code !== 0) {
                message.error('获取信息失败,请稍后再试~');
                return;
              }
              yield put({ type: 'closeLoading' });
              yield put({
                            type: 'savedataonedata',
                            payload: response.data,
                        });
              // 这个return很重要,不然上面的 dispatch后的then是获取不到数据的!!!!!
              return response.data;
    },
    },
    reducers: {
         savedataonedata(state, action) {
          return {
            ...state,
            dataOneData:action.payload,
          };
    },
    }
}

最后,service文件

export async function dataOneData(params,dataid) {
  return request(`/data/${dataid}/rel`, {
    method: 'GET',
    params,
  });
}

因为我们把 请求拆分成 路由 model 业务代码

所以,有其他文件要修改,所以请对你自己代码,选择性修改!

这几天我查询到并参考的链接:

https://github.com/ant-design/ant-design/issues/6675

https://www.jianshu.com/p/b49fe87d2153

https://segmentfault.com/q/1010000008673763


欢迎转载,但请附上原文地址哦,尊重原创,谢谢大家 本文地址: http://www.iphpt.com/detail/129/

当你能力不能满足你的野心的时候,你就该沉下心来学习