对 Axios 响应中的数据进行排序并设置为 useReducer 负载
Sort data in Axios response and set as useReducer payload
我正在使用 axios 将来自 api 的数据调用到我的 React 应用程序中,如下所示:
const adapter = axios.create({
baseURL: "http://localhost:4000",
});
const getData = async () => {
const response = await adapter.get("/test-api");
return response.data;
};
这个 运行 在一个上下文中,我有一个基本的 reducer 函数,我传递给上下文:
const initialState = {
loading: true,
error: false,
data: [],
errorMessage: "",
};
const reducer = (state, action) => {
switch (action.type) {
case ACTIONS.FETCH_SUCCESS:
return {
...state,
loading: false,
data: action.payload,
};
case ACTIONS.FETCH_ERROR:
return {
...state,
error: true,
errorMessage: "Error loading data",
};
default:
return state;
}
};
我从 api 返回的数据的形状如下:
{
"data": [
{
"id": 1,
"name": "Name 1",
"items": [
{
"id": "klqo1gnh",
"name": "Item 1",
"date": "2019-05-12"
}
]
},
{
"id": 2,
"name": "Name 2",
"items": [
{
"id": "klqo2fho",
"name": "Item 1",
"date": "2021-05-05"
},
{
"id": "klro8wip",
"name": "Item 2",
"date": "2012-05-05"
}
]
}
]
}
并且我编写了一个简单的函数,使用 moment
:
查找其嵌套数组 items
具有最早日期的项目
const sortDataByDate = (items) => {
return items.sort((first, second) => {
if (moment(first.items.date).isSame(second.items.date)) {
return -1;
} else if (moment(first.items.date).isBefore(second.items.date)) {
return -1;
} else {
return 1;
}
});
};
然后我在这个函数中获取所有内容:
const fetchData = useCallback(async () => {
try {
await getData().then((response) => {
dispatch({
type: ACTIONS.FETCH_SUCCESS,
payload: response,
});
});
} catch (error) {
dispatch({ type: ACTIONS.FETCH_ERROR });
}
}, []);
然后我 运行 fetchData()
在 useEffect
我的上下文中:
useEffect(() => {
fetchData();
}, [fetchData]);
说了这么多,问题来了。我的 sortDataByDate
功能偶尔会起作用;有时数据的排序是正确的,有时则不是。我想要做的是获取我的数据,使用 sortDataByDate
对其进行排序,然后使用排序后的数据设置 payload
,因此它是全局排序而不是在组件级别排序。在我的 App
中,它似乎始终如一地工作,所以我认为我在上下文级别上遗漏了一些东西。有什么建议吗?
您需要先对内部项目进行排序并获取最早的日期:
const sortDataByDate = (items) => {
return items.sort((first, second) => {
if (moment(first.items[0].date).isSame(second.items[0].date)) {
return -1;
} else if (moment(first.items[0].date).isBefore(second.items[0].date)) {
return -1;
} else {
return 1;
}
});
};
我正在使用 axios 将来自 api 的数据调用到我的 React 应用程序中,如下所示:
const adapter = axios.create({
baseURL: "http://localhost:4000",
});
const getData = async () => {
const response = await adapter.get("/test-api");
return response.data;
};
这个 运行 在一个上下文中,我有一个基本的 reducer 函数,我传递给上下文:
const initialState = {
loading: true,
error: false,
data: [],
errorMessage: "",
};
const reducer = (state, action) => {
switch (action.type) {
case ACTIONS.FETCH_SUCCESS:
return {
...state,
loading: false,
data: action.payload,
};
case ACTIONS.FETCH_ERROR:
return {
...state,
error: true,
errorMessage: "Error loading data",
};
default:
return state;
}
};
我从 api 返回的数据的形状如下:
{
"data": [
{
"id": 1,
"name": "Name 1",
"items": [
{
"id": "klqo1gnh",
"name": "Item 1",
"date": "2019-05-12"
}
]
},
{
"id": 2,
"name": "Name 2",
"items": [
{
"id": "klqo2fho",
"name": "Item 1",
"date": "2021-05-05"
},
{
"id": "klro8wip",
"name": "Item 2",
"date": "2012-05-05"
}
]
}
]
}
并且我编写了一个简单的函数,使用 moment
:
items
具有最早日期的项目
const sortDataByDate = (items) => {
return items.sort((first, second) => {
if (moment(first.items.date).isSame(second.items.date)) {
return -1;
} else if (moment(first.items.date).isBefore(second.items.date)) {
return -1;
} else {
return 1;
}
});
};
然后我在这个函数中获取所有内容:
const fetchData = useCallback(async () => {
try {
await getData().then((response) => {
dispatch({
type: ACTIONS.FETCH_SUCCESS,
payload: response,
});
});
} catch (error) {
dispatch({ type: ACTIONS.FETCH_ERROR });
}
}, []);
然后我 运行 fetchData()
在 useEffect
我的上下文中:
useEffect(() => {
fetchData();
}, [fetchData]);
说了这么多,问题来了。我的 sortDataByDate
功能偶尔会起作用;有时数据的排序是正确的,有时则不是。我想要做的是获取我的数据,使用 sortDataByDate
对其进行排序,然后使用排序后的数据设置 payload
,因此它是全局排序而不是在组件级别排序。在我的 App
中,它似乎始终如一地工作,所以我认为我在上下文级别上遗漏了一些东西。有什么建议吗?
您需要先对内部项目进行排序并获取最早的日期:
const sortDataByDate = (items) => {
return items.sort((first, second) => {
if (moment(first.items[0].date).isSame(second.items[0].date)) {
return -1;
} else if (moment(first.items[0].date).isBefore(second.items[0].date)) {
return -1;
} else {
return 1;
}
});
};