搜索列表的需求:根据URL里面的变化,实时刷新列表
class 组件的写法
class List extends PureComponent {
constructor(props) {
super(props)
const {
location: { query }
} = props
this.state = {
filter: {
...query
}
}
}
componentDidUpdate() {
const {
location: { query }
} = this.props
if (this._isFilterSame(this.state.filter, query)) {
return
}
this.setState(
{
filter: {
...query
}
},
() => {
this.getList()
}
)
}
_isFilterSame = (previous, current) => {
if (previous.pageNumber !== current.pageNumber) {
return false
}
if (previous.pageSize !== current.pageSize) {
return false
}
if (previous.searchText !== current.searchText) {
return false
}
return true
}
getList = () => {
const {
dispatch,
location: { query }
} = this.props
const { pageNumber = 1, pageSize = 10, searchText } = query
const data = {
pageNumber,
pageSize
}
if (searchText) {
data.searchText = searchText
}
dispatch({
type: 'enterpriseModel/getEnterpriseList',
payload: data
})
}
getColumns = () => {
return [
{
title: '企业名称',
align: 'left',
dataIndex: 'name'
},
{
title: '企业英文名称',
align: 'center',
dataIndex: 'nameEn'
},
{
title: '企业简称',
align: 'left',
dataIndex: 'shortName'
},
{
title: '域名',
align: 'center',
dataIndex: 'domain'
}
]
}
_changePageIndex = pageNumber => {
const {
location: { query }
} = this.props
this.delPath(query)
query.pageNumber = pageNumber
this.pushRouter(query)
}
_onShowSizeChange = (pageNumber, pageSize) => {
const {
location: { query }
} = this.props
query.pageNumber = `${pageNumber}`
query.pageSize = `${pageSize}`
this.pushRouter(query)
}
delPath = query => {
if (!query.countPerPage) {
query.pageNumber = 1
}
if (!query.countPerPage) {
query.pageSize = 10
}
}
pushRouter = query => {
const url = `/enterprise?${qs.stringify(query)}`
router.push(url)
}
basicTableProps = () => {
const {
enterpriseList,
total,
location: {
query: { pageSize, pageNumber }
}
} = this.props
return {
rowKey: 'id',
dataSource: enterpriseList || [],
columns: this.getColumns(),
className: styles.table,
pagination: {
showQuickJumper: false,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100', '200'],
onChange: this._changePageIndex,
onShowSizeChange: this._onShowSizeChange,
total: total || null,
pageSize: parseInt(pageSize, 10),
current: parseInt(pageNumber, 10),
showTotal: () => {
return `${total}条记录`
}
}
}
}
content = () => {
return (
<div className={styles.tableDiv}>
<Table {...this.basicTableProps}></Table>
</div>
)
}
header = () => {
const { searchText } = this.state
return (
<div className={styles.header}>
<Search
className={styles.search}
placeholder={'请输入企业名称/域名'}
onChange={this.handleChange}
onSearch={this.handleSearch}
value={searchText}
></Search>
</div>
)
}
render() {
const { loading } = this.props
return (
<Spin spinning={loading.effects['enterpriseModel/getEnterpriseList']}>
{this.header()}
{this.content()}
</Spin>
)
}
}
hook的写法
function List(props) {
const {
dispatch,
loading,
enterpriseList,
total,
location: { query }
} = props
const { pageNumber = 1, pageSize = 10, searchText: initText } = query
const getList = useCallback(
query => {
const { pageNumber = 1, pageSize = 10, searchText } = query
const data = {
pageNumber,
pageSize
}
if (searchText) {
data.searchText = searchText
}
dispatch({
type: 'enterpriseModel/getEnterpriseList',
payload: data
})
},
[dispatch]
)
useEffect(() => {
getList(query)
}, [getList, query])
const [searchText, changeValue] = useState(initText)
const getColumns = () => {
return [
{
title: '企业名称',
align: 'left',
dataIndex: 'name'
},
{
title: '企业英文名称',
align: 'center',
dataIndex: 'nameEn'
},
{
title: '企业简称',
align: 'left',
dataIndex: 'shortName'
},
{
title: '域名',
align: 'center',
dataIndex: 'domain'
}
]
}
const _changePageIndex = pageNumber => {
delPath(query)
query.pageNumber = pageNumber
pushRouter()
}
const _onShowSizeChange = (pageNumber, pageSize) => {
query.pageNumber = `${pageNumber}`
query.pageSize = `${pageSize}`
pushRouter()
}
const pushRouter = () => {
const url = `/enterprise?${qs.stringify(query)}`
router.push(url)
}
const basicTableProps = {
rowKey: 'id',
dataSource: enterpriseList || [],
columns: getColumns(),
className: styles.table,
pagination: {
showQuickJumper: false,
showSizeChanger: true,
pageSizeOptions: ['10', '20', '50', '100', '200'],
onChange: _changePageIndex,
onShowSizeChange: _onShowSizeChange,
total: total || null,
pageSize: parseInt(pageSize, 10),
current: parseInt(pageNumber, 10),
showTotal: () => {
return `${total}条记录`
}
}
}
const handleChange = e => {
const { value } = e.target
changeValue(value)
}
const handleSearch = value => {
delPath(query)
query.searchText = value
if (!value) {
delete query.searchText
}
pushRouter()
}
const delPath = query => {
if (!query.countPerPage) {
query.pageNumber = 1
}
if (!query.countPerPage) {
query.pageSize = 10
}
}
const content = useMemo(() => {
return (
<div className={styles.tableDiv}>
<Table {...basicTableProps}></Table>
</div>
)
}, [basicTableProps])
const header = () => {
return (
<div className={styles.header}>
<Search
className={styles.search}
placeholder={'请输入企业名称/域名'}
onChange={handleChange}
onSearch={handleSearch}
value={searchText}
></Search>
</div>
)
}
return (
<Spin spinning={loading.effects['enterpriseModel/getEnterpriseList']}>
{header()}
{content}
</Spin>
)
}
最后
其实对比下来,hook的代码量少一些,而且简单明了, 在class组件里面我要通过_isFilterSame函数来判断,URL里面的参数有没有变化, 而在hook里面我只需要把query参数传到useEffect里面,hook 自动做到了监听,省去了很多判断