我想切换到功能风格与钩子,但仍然无法找到出路。例如,我有一个表示表的抽象类。
import React from "react";
import ErrorBoundary from "Components/ErrorBoundary";
import { Link } from "react-router-dom";
import { Table, Divider, Alert, Popconfirm } from "antd";
export default class AbstractTable extends React.Component {
constructor( props ) {
super( props );
this.state = {
pagination: {
current: 1,
pageSize: 50,
total: 0
},
filterParams: {},
sortParams: {},
filterParams: {}
}
this.url = this.props.baseUrl;
this.table = this.constructor.displayName;
this.addButtonText = `New record`;
}
renderActions = ( text, record ) => (
<span>
<Link to={ `${ this.url }/${ record.id }` }>Edit</Link>
<Divider type="vertical" />
<Popconfirm placement="topRight" title="Are you sure to delete this record?"
onConfirm={ () => this.removeRecord( record.id ) } okText="Yes" cancelText="No">
<a href="#">Delete</a>
</Popconfirm>
</span>
)
removeRecord( id ) {
this.api.remove( id );
this.props.actions.loadTable( this.table, this.api );
}
/**
* Get query params from filters given as key/value object literal like
* { filter[firstName]: "val1", filter[lastName]: "val2" }
*/
static getFilterParams( filters ) {
return Object.entries( filters ).reduce(( carry, pair ) => {
carry[ `filter[${ pair[ 0 ] }]` ] = pair[ 1 ];
return carry;
}, {});
}
// Overridable
hookOnTableChange() {
}
/**
* Send XHR to update table content
*/
onTableChange = ( pagination, filters, sorter ) => {
const pager = { ...this.state.pagination };
// Intercept incoming pagination, filters, sorter, can map field for sort=true
this.hookOnTableChange( pagination, filters, sorter );
pager.current = pagination.current;
// Normalize filters from {firstName: [ "value1" ], lastName: [ "value2" ]} to key-value object
const filterMap = Object.entries( filters ).reduce( ( carry, pair ) => {
if ( pair[ 1 ] === null ) {
return carry;
}
carry[ pair[ 0 ] ] = pair[ 1 ].join( "," );
return carry;
}, {}),
filterParams = { ...this.state.filterParams, ...filterMap };
const sortParams = {
sortField: sorter.field,
sortOrder: sorter.order === "ascend" ? "ASC" : "DESC",
}
this.setState({
pagination: pager,
sortParams,
filterParams
});
this.fetch({
pageSize: pagination.pageSize,
current: pagination.current,
...sortParams,
...AbstractTable.getFilterParams( filterParams )
});
}
fetch = ( params = {} ) => {
this.props.actions.loadTable( this.table, this.api, params );
}
async componentDidMount() {
const { preloaded } = this.props.store.app.tables[ this.table ];
if ( preloaded ) {
return;
}
this.fetch();
}
addRecord = ( e ) => {
e.preventDefault();
}
render() {
const { rows, total, loading, errorMessage } = this.props.store.app.tables[ this.table ];
return (<ErrorBoundary>
{ errorMessage ? <Alert
message="Error"
description={ errorMessage }
type="error"
/> : null }
<Table columns={ this.state.columns }
loading={ loading }
dataSource={ rows }
onChange={ this.onTableChange }
pagination = { {
...this.state.pagination,
total
}}
/>
</ErrorBoundary>);
}
};特定表扩展了抽象表,它重用共享方法。如果有必要的话,它可能会超过一些。例如。
export default class SettingsProjectTable extends AbstractTable {
constructor( props ) {
super( props );
this.api = api;
this.state = {
columns: [{
title: "Name",
dataIndex: "name",
sorter: true
},
{
title: "Environment",
dataIndex: "env",
sorter: true,
filters: [
{
text: 'test',
value: 'test',
},
{
text: 'live',
value: 'live',
}
]
},
{
title: "Actions",
key: "action",
width: "120px",
render: this.renderActions
}]
}
}
};那么,什么才是有效的重构呢?我是否应该制作一个组件,并传递细节和与属性交替的方法?
发布于 2022-03-28 14:55:52
“设置表”不需要单独的组件。它只是一个“表”组件,具有通过道具传递给它的不同数据。
将API和分页特性提取到可重用的"provider“组件中可能是个好主意。然后,提供程序包装表并向其子表生成值;在您的示例中,表组件。
<ApiProvider>
<MyTable data={data} columns={['id','name','date']}>
</ApiProvider>这样做的全部目的是使您的组件更通用,因此更可重用。通过使您的表“哑”(没有直接的API访问),它可以在需要数据驱动的表的任何地方重用。通过通过提供程序访问API,可以向任何子组件(而不仅仅是表)提供数据。
您还可以通过useContext提供在应用程序中任何深度都可以访问的数据。
https://stackoverflow.com/questions/71649167
复制相似问题