【发布时间】:2020-07-09 15:14:03
【问题描述】:
我已经制作了这个自定义钩子来使用 fetcher 获取数据并返回带有数据的状态以显示在 antd 表中(喜欢它们)。 我不确定这是使用钩子的正确方法,我已经在我有疑问的代码中添加了 cmets。
import { useEffect, useReducer } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import queryString from 'query-string'
const initialState = { data: [], loading: true };
const fetchData = (fetcher, params, dispatch) => {
//in this case i need to change my state to loading, the reducer will do the trick, but i fill this kinda triky, should i call the fatcher after the dispatch end using an effect?
dispatch({ type: 'FETCHING' })
fetcher({ ...params, page: params.page > 0 ? params.page - 1 : params.page }, response => dispatch({ type: 'DATA_RECEIVED', payload: response.data }));
return () => {
console.log('unmounting useGridDataFetch')
};
}
const handlePageChange = (page, history, location) => {
const qparams = queryString.parse(location.search)
const qs = Object.keys(qparams).map(key => key != 'page' ? `&${key}=${qparams[key]}` : '')
history.push(`${history.location.pathname}?page=${page}${qs.reduce((acc,val)=> acc + val , '')}`)
}
const useGridDataFetch = (fetcher, initialParams) => {
const location = useLocation()
const history = useHistory()
const params = { ...initialParams, ...queryString.parse(location.search) }
// to use history and location inside my reducer to change the querystring on page change, i had to put the reducer definition inside the body of the hook, is there a better way?
const reducer = (state, action) => {
switch (action.type) {
case 'FETCHING':
return { loading: true };
case 'DATA_RECEIVED':
const pagination = {
pageSize: action.payload.pageable.pageSize,
current: action.payload.pageable.pageNumber + 1,
total: action.payload.totalElements,
onChange: page => handlePageChange(page, history, location)
}
return { dataSource: action.payload.content, loading: false, pagination };
default:
throw new Error();
}
}
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => fetchData(fetcher, params, dispatch), [location.search])
return [state, (_params) => fetchData(fetcher, { ...params, ..._params }, dispatch)]
}
export default useGridDataFetch
一般来说,您可以给我的每一个改进我的代码的提示都会很感激。
谢谢。
【问题讨论】:
标签: javascript reactjs react-router react-hooks antd