有没有一种方法可以让我们的加载状态类似于在client-side上获取数据时的加载状态
我想要加载状态的原因是有一些类似加载骨架的东西,例如react-loading-skeleton
在客户端,我们可以这样做:
import useSWR from 'swr'
const fetcher = (url) => fetch(url).then((res) => res.json())
function Profile() {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}但是对于SSR (getServerSideProps),我不知道这是否可行,例如,我们可以有一个加载状态吗?
function AllPostsPage(props) {
const router = useRouter();
const { posts } = props;
function findPostsHandler(year, month) {
const fullPath = `/posts/${year}/${month}`;
router.push(fullPath);
}
if (!data) return <div>loading...</div>; // Would not work with SSR
return (
<Fragment>
<PostsSearch onSearch={findPostsHandler} />
<PosttList items={posts} />
</Fragment>
);
}
export async function getServerSideProps() {
const posts = await getAllPosts();
return {
props: {
posts: posts,
},
};
}
export default AllPostsPage;最近,Next.js发布了getServerSideProps should support props value as Promise https://github.com/vercel/next.js/pull/28607,我们可以做出承诺,但不确定如何实现它,是否有加载状态,或者这是否可以实现。他们的例子显示:
export async function getServerSideProps() {
return {
props: (async function () {
return {
text: 'promise value',
}
})(),
}
}发布于 2021-11-03 15:04:22
您可以在_app.js上设置加载状态
import Router from "next/router";
export default function App({ Component, pageProps }) {
const [loading, setLoading] = React.useState(false);
React.useEffect(() => {
const start = () => {
console.log("start");
setLoading(true);
};
const end = () => {
console.log("findished");
setLoading(false);
};
Router.events.on("routeChangeStart", start);
Router.events.on("routeChangeComplete", end);
Router.events.on("routeChangeError", end);
return () => {
Router.events.off("routeChangeStart", start);
Router.events.off("routeChangeComplete", end);
Router.events.off("routeChangeError", end);
};
}, []);
return (
<>
{loading ? (
<h1>Loading...</h1>
) : (
<Component {...pageProps} />
)}
</>
);
}发布于 2021-09-21 05:10:04
我还没有尝试过这个功能,但理论上我认为它应该可以工作。如果您只想让客户端通过服务器属性访问promise,请尝试如下所示。基本上,你的props是一个异步的lambda函数,所以你可以在里面做任何需要的工作,例如,获取数据等等,所以客户端应该把props作为一个承诺来访问并等待它。
export async function getServerSideProps() {
return {
props: (async function () {
const posts = await getAllPosts();
return {
posts: posts,
}
})(),
}
}
//then on client-side you can do the following or similar to set loading state
function MyComponent(props) {
const [isLoading, setIsLoading] = useState(false);
const [posts, setPosts] = useState({});
useEffect(async () => {
setIsLoading(true);
const tempPosts = await props?.posts;
setPosts(posts);
setIsLoading(false);
}, [])
return (
{isLoading && <div>loading...</div>}
);
}
export default MyComponent;发布于 2021-09-21 06:30:13
您可以修改_app.js组件,使其在getServerSideProps执行异步工作时显示正在加载的组件,如https://stackoverflow.com/a/60756105/13824894所示。这将适用于您的应用程序中的每个页面过渡。
您仍然可以在客户端独立使用您的加载逻辑。
https://stackoverflow.com/questions/69263469
复制相似问题