# __ .______ __ __ .______ .___________. ______ ______ .___ ___. # | | | _ \ | | | | | _ \ | | / | / __ \ | \/ | # | | | |_) | | |__| | | |_) | `---| |----` | ,----'| | | | | \ / | # | | | ___/ | __ | | ___/ | | | | | | | | | |\/| | # | | | | | | | | | | | | __ | `----.| `--' | | | | | # |__| | _| |__| |__| | _| |__| (__) \______| \______/ |__| |__| # ""$o o$"" ""$o o$" o "$""""o "o $" o""" $" "$o "$o" $o " $ o$" "$o $$$o$$$$o$$$$ $" "oooo o "" ""$$$$$$$$""o"" oo oooo" "$$$$$$oo"oo$$$o" o$$$$oo" o$$$o "o$$$$$$$ "$ $$$$$$$$$oo o$$$$$$$$$o"$" $ $$$ $$$$$$ o$$$$$$ "$$o"o $ $$$$o $$$$$$ $$$$$$$ $$$$o"o $ $$$$$ $$$$$" "$$$$$ $$$$$$ $ $o""""" """" """ """"""$" $ o$$$$$"""$$$$$"$$$$$""$$$$$ooo"o $ o"$o $$$$$$$$oo$$$$$$$$o $$"" $ oo$ "$$$$$$$$$$$$$$$$$$$$" o" o $oo o$$$"$ $$o"o $$$$$$$"" "$$$$$$$ o$$ $$$$o IPHPT BUG o$$$$" $ $$$$ o "$$$$$oo o$$$$$$ "o$$$$ $ $$$$$ o$$"" $ $$$$$o" "$$$$$$$$$$$$$ o o$$$$$o$ "" $$ $$" $ $$$" o"o$$$$$$$$$$$$ " "$$$ $ $$o o$$ "o $$ " $$$$$$$$$$$"o "$$ $ $$$ $$$ oo$ $ o""$$""$$$o " $"o$o $$$o o$$$$ o$$$"o"$oo$$$$o" o $o $$$$$oo$ $$$$o $$$$ $$$$ $$$$" $ $$$$$"" $$ o$$$ """$$$$"o" "$$$o "$$$o $$$" o """ $ $$$oo $$$$o" $$ o$$$"o" """"$ o$$$ o$" $$$ $ "$"" o$"o"$$o$$$$ "$$"o" o$$ "$oo $ " $$o $ "oo$"o$$$"o$o"$$$$o" o" $$$ ""$o $$ $$$o "o$$o$"$$"$$o$$o$$"$$o" $$$ ""o $$$ ""$$$ $$$$$$ $$$$ $" $$$$ $$ $$$$ $$$$"$$$o$ $"" $$$ $$$$ "$$$ """ $$$$ $$"" "$$ oo$" $ooo $ "$$ antd react table扩展行(expandedRowRender)异步记载数据再渲染问题   -  叶落山城秋

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


欢迎转载,但请附上原文地址哦,尊重原创,谢谢大家 本文地址: https://www.iphpt.com/detail/129/
本站(PHP --> Golang)已重构,代码开源

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