由于使用 NextJS 的序列化问题,无法从服务器获取数据?
Unable to fetch data from server due to serialization problem using NextJS?
我目前正在使用 axios 和 NextJS。
目前我的组件中有这段代码:
export async function getServerSideProps(context) {
const data = await getVideo(context.query.id);
console.log('data: ', data);
// console.log('context: ', context);
console.log('context params: ', context.params);
console.log('context query: ', context.query);
if (!data) {
return { notFound: true };
}
return {
props: {
videoId: context.params.id,
videoSlug: context.params.slug,
videoContent: data
}
};
}
这个 getserverSideProps 调用了 getVideo
的函数,看起来完全像这样:
export const getVideo = (id) => async (dispatch) => {
dispatch({ type: CLEAR_VIDEO });
try {
console.log('Action file: ', id);
const res = await api.get(`/videos/${id}`);
return dispatch({
type: GET_VIDEO,
payload: res.data
});
} catch (err) {
dispatch({
type: VIDEO_ERROR,
payload: { msg: err.response?.statusText, status: err.response?.status }
});
}
};
所述函数通过我的 api 函数向后端发出请求:
import axios from 'axios';
import { LOGOUT } from '../actions/types';
import { API_URL } from '../config';
const api = axios.create({
baseURL: `${API_URL}/api/v1`,
headers: {
'Content-Type': `application/json`
}
});
/**
intercept any error responses from the api
and check if the token is no longer valid.
ie. Token has expired
logout the user if the token has expired
**/
api.interceptors.response.use(
(res) => {
res;
console.log('Res: ', res.data);
},
(err) => {
if (err?.response?.status === 401) {
typeof window !== 'undefined' &&
window.__NEXT_REDUX_WRAPPER_STORE__.dispatch({ type: LOGOUT });
}
return Promise.reject(err);
}
);
export default api;
在执行 POST、PUT、PATCH 请求时效果很好。
如您所见,我正在执行 console.log('data: ',data)
,但每当我阅读终端时它 returns [AsyncFunction (anonymous)]
;另一方面,前端 returns 这个错误:
Server Error Error: Error serializing .videoContent
returned from
getServerSideProps
in "/videos/[id]/[slug]". Reason: function
cannot be serialized as JSON. Please only return JSON serializable
data types.
有人知道怎么解决吗?
注意:我正在使用 react-redux、redux 和 next-redux-wrapper。
那是因为你的getVideo
函数returns另一个函数。正确的调用方式是:
const data = await getVideo(context.query.id)()//<- pass in the dispatch here
但是你不应该那样在后端使用 redux
。我认为你可以完全删除它。
export const getVideo async (id) => {
try {
console.log('Action file: ', id);
const res = await api.get(`/videos/${id}`);
return res.data
});
} catch (err) {
return { msg: err.response?.statusText, status: err.response?.status }
}
};
// call
const data = await getVideo(context.query.id)
我目前正在使用 axios 和 NextJS。
目前我的组件中有这段代码:
export async function getServerSideProps(context) {
const data = await getVideo(context.query.id);
console.log('data: ', data);
// console.log('context: ', context);
console.log('context params: ', context.params);
console.log('context query: ', context.query);
if (!data) {
return { notFound: true };
}
return {
props: {
videoId: context.params.id,
videoSlug: context.params.slug,
videoContent: data
}
};
}
这个 getserverSideProps 调用了 getVideo
的函数,看起来完全像这样:
export const getVideo = (id) => async (dispatch) => {
dispatch({ type: CLEAR_VIDEO });
try {
console.log('Action file: ', id);
const res = await api.get(`/videos/${id}`);
return dispatch({
type: GET_VIDEO,
payload: res.data
});
} catch (err) {
dispatch({
type: VIDEO_ERROR,
payload: { msg: err.response?.statusText, status: err.response?.status }
});
}
};
所述函数通过我的 api 函数向后端发出请求:
import axios from 'axios';
import { LOGOUT } from '../actions/types';
import { API_URL } from '../config';
const api = axios.create({
baseURL: `${API_URL}/api/v1`,
headers: {
'Content-Type': `application/json`
}
});
/**
intercept any error responses from the api
and check if the token is no longer valid.
ie. Token has expired
logout the user if the token has expired
**/
api.interceptors.response.use(
(res) => {
res;
console.log('Res: ', res.data);
},
(err) => {
if (err?.response?.status === 401) {
typeof window !== 'undefined' &&
window.__NEXT_REDUX_WRAPPER_STORE__.dispatch({ type: LOGOUT });
}
return Promise.reject(err);
}
);
export default api;
在执行 POST、PUT、PATCH 请求时效果很好。
如您所见,我正在执行 console.log('data: ',data)
,但每当我阅读终端时它 returns [AsyncFunction (anonymous)]
;另一方面,前端 returns 这个错误:
Server Error Error: Error serializing
.videoContent
returned fromgetServerSideProps
in "/videos/[id]/[slug]". Reason:function
cannot be serialized as JSON. Please only return JSON serializable data types.
有人知道怎么解决吗?
注意:我正在使用 react-redux、redux 和 next-redux-wrapper。
那是因为你的getVideo
函数returns另一个函数。正确的调用方式是:
const data = await getVideo(context.query.id)()//<- pass in the dispatch here
但是你不应该那样在后端使用 redux
。我认为你可以完全删除它。
export const getVideo async (id) => {
try {
console.log('Action file: ', id);
const res = await api.get(`/videos/${id}`);
return res.data
});
} catch (err) {
return { msg: err.response?.statusText, status: err.response?.status }
}
};
// call
const data = await getVideo(context.query.id)