使用 NextJS 在 getServerSideProps 中没有可用数据时显示 div?

Posted

技术标签:

【中文标题】使用 NextJS 在 getServerSideProps 中没有可用数据时显示 div?【英文标题】:Show div when there's not data available in getServerSideProps with NextJS? 【发布时间】:2021-07-27 07:46:17 【问题描述】:

好的,这是我关于 NextJS 的第三篇文章。

我目前正在制作一个搜索页面,该页面需要根据在 URL 中找到的关键字从 3 个端点获取数据;如果未找到数据,请在正确的调用中显示一条消息。

即使在 1-2 个端点中找到数据,当前行为也会引发错误:

import  useEffect, useState, useContext  from 'react';
import  withRouter  from 'next/router';
// ACTIONS
import  getProducersFromServer  from '@/actions/producer';
import  getVideosFromServer  from '@/actions/video';
import  getProfilesFromServer  from '@/actions/profile';
// HELPERS
import Layout from '@/layout/Layout';
import  PUBLIC_URL  from '../../config';
import NothingFoundAlert from '@/layout/NothingFoundAlert';
import AuthContext from '@/routing/authContext';
// REACTBOOTSTRAP
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
// NESTED COMPONENTS
import SearchMenu from './SearchMenu';
import SingleProducer from '../producers/singleProducer';
import SingleVideo from '../videos/singleVideo';
import SingleProfile from '../profiles/singleProfile';

export const getServerSideProps = async (context) => 
  const keyword = context.query.keyword;
  const params = `?keyword=$keyword&page=$context.query.page&limit=$context.query.limit&sort=$context.query.sort&status=$context.query.status`;
  const producers = (await getProducersFromServer(params)()) || [];
  const videos = (await getVideosFromServer(params)()) || [];
  const params2 = `?keyword=$keyword&page=$context.query.page&limit=$context.query.limit&sort=$context.query.sort&isEmailConfirmed=true`;
  const profiles = (await getProfilesFromServer(params2)()) || [];

  return 
    props: 
      params: params,
      params2: params2,
      keyword: keyword,
      serverProducers: producers?.data,
      serverVideos: videos?.data,
      serverProfiles: profiles?.data
    
  ;
;

const All = (
  params,
  params2,
  keyword,
  serverProducers,
  serverVideos,
  serverProfiles,
  router
) => 
  const [searchProducerResults, setSearchProducerResults] = useState([]);
  const [searchVideoResults, setSearchVideoResults] = useState([]);
  const [searchProfileResults, setSearchProfileResults] = useState([]);

  useEffect(() => 
    setSearchProducerResults(serverProducers);
    setSearchVideoResults(serverVideos);
    setSearchProfileResults(serverProfiles);
  , [params]);
  const  auth  = useContext(AuthContext);
  return (
    <Layout
      title=`Search Results of $keyword`
      description=`Search results`
      author=`Kevin Fonseca`
      sectionClass=`mb-3`
      containerClass=`container`
      canonical=`$PUBLIC_URL`
      url=`search$params`
    >
      <SearchMenu params=params params2=params2 />
      <div
        className=
          auth?.user?.data?.settings.theme.themeContainer
            ? auth?.user?.data.settings.theme.themeContainer
            : `container`
        
      >
        <Row>
          <Col xl=`12` lg=`12`>
            searchProducerResults?.length > 0 ? (
              <>
                <h4 className=`my-2 mb-3`>
                  Producers (totalProducerResults)
                </h4>
                searchProducerResults.map((producer, index) => (
                  <SingleProducer key=producer._id producer=producer />
                ))
              </>
            ) : (
              <NothingFoundAlert />
            )
            searchVideoResults?.length > 0 ? (
              <>
                <hr />
                <h4 className=`my-2 mb-3`>Videos (totalVideoResults)</h4>
                <div className=`recommendedVideos_videos`>
                  searchVideoResults.map((video, index) => (
                    <SingleVideo key=video._id video=video />
                  ))
                </div>
              </>
            ) : (
              <NothingFoundAlert />
            )
            searchProfileResults?.length > 0 ? (
              <>
                <hr />
                <h4 className=`my-2 mb-3`>
                  Profiles (totalProfileResults)
                </h4>
                <div className=`profiles-container`>
                  searchProfileResults
                    .filter((profile) => profile._id !== auth?.user.data._id)
                    .map((profile, index) => (
                      <SingleProfile
                        key=profile._id
                        profile=profile
                        auth=auth
                      />
                    ))
                </div>
              </>
            ) : (
              <NothingFoundAlert />
            )
          </Col>
        </Row>
      </div>
    </Layout>
  );
;

export default withRouter(All);

在上面的代码中,我试图在每个变量中显示NothingFoundAlert 组件,但它当前会引发以下错误:

Error: Error serializing `.serverProducers` returned from `getServerSideProps` in "/search".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

注意:我使用的是快递

【问题讨论】:

【参考方案1】:

我刚刚解决了,解决方法是在找不到数据的时候为每个变量声明一个空数组:

serverProducers: producers?.data || [],
serverVideos: videos?.data || [],
serverProfiles: profiles?.data || []

仍然不确定为什么我需要再次创建第二个|| [],但这是唯一可行的方法。

【讨论】:

以上是关于使用 NextJS 在 getServerSideProps 中没有可用数据时显示 div?的主要内容,如果未能解决你的问题,请参考以下文章

nextjs - 在开发模式下使用 _error.js

使用 NextJS + Express 在本地主机上进行 HTTPS

NextJS - 无法在 Tailwind CSS 中使用自定义颜色

如何在客户端 NextJS 中使用 Apollo GraphQL 订阅?

如何在 Storybook 中使用 NextJS 的 'useRouter()' 钩子

Nextjs 在构建模式下使用 Tailwind 中断布局