代码之家  ›  专栏  ›  技术社区  ›  daniel sas

NextJS和React无法读取未定义的属性,element.map不是函数

  •  0
  • daniel sas  · 技术社区  · 1 年前

    我正在使用NextJS getServerSideProps 用Prisma从数据库中获取一些数据。在开发环境中,我没有任何问题。但在部署vercel时,我经常遇到问题。

    以下是我所做的:

    1. 我创建了从数据库获取Toto列表的API路由。在这个函数中,我只需返回购物列表数组,如下所示:
    import prisma from '../../../lib/prisma'
    
    
    
    export default async function handler(req, res) {
    
        const { userId } = req.query;
        if (req.method === 'GET') {
          try {
            const shoppingLists = await prisma.List.findMany({ where: { userId: userId[0] }});
            res.status(200).send(shoppingLists);
          } 
          catch (error) {
            console.log(error);
            res.status(500).json({ message: 'Something went wrong. Please try again'});  
          }
        }
        else {
          res.status(500).json({message: 'Invalid method requested!'});
        }
    }
    
    1. 之后,我创建了一个名为抽象层的单独文件夹,在这里我可以进行所有的DB交互。我在用斧头。在这个函数中,我获取数据并将其作为list.data返回;
    
    // Get all lists
    export const getAllLists = async userId => {
        try {
            const lists = await axios.get(`https://next-shopping-list.vercel.app/api/get-all-lists/${userId}`, { 
                headers: { "Accept-Encoding": "gzip,deflate,compress" } // This is taken from internet because I had other errors "invalid file"
            });
            return lists.data;    
        } 
        catch (error) {
            console.log('Abstraction layer error: ', error);
            return 'Something went wrong. Please try again later';
        }
    }
    

    //将包含get服务器端props和return()的组件(Dashboard) 3.问题来了。我使用SSR是因为我也想保护这个页面。在这个函数中,我使用函数 getAllLists 从“抽象层”返回带有“列表”属性的购物列表。。。

    export const getServerSideProps = async context => {
    
      // get sessions with added user Id in the session object
      const session = await requireAuthentication(context);
    
      // Get all lists
      const shoppingLists = await getAllLists(session?.user.userId);
    console.log(shoppingLists);
    
      if (!session) {
        return {
          redirect: {
            destination: '/signup',
            permanent: false
          }
        }
      }
      
      else {
        return {
          props: {
            newSession: session,
            lists:       shoppingLists
          }
        }
      }
    }
    
    1. 创建组件后,我开始在映射列表数组时出错,并抛出两个错误:
    • “props.lists.map()…”不是函数。
    • 无法读取未定义的属性(读取“length”)
    const Lists = props => {
    
        const router = useRouter();
        console.log(props.lists);
    
    
        const handleDeleteList = async listId => {
            const status = await deleteList(listId);
            console.log(status);      
            if (status.status === 201) {
                router.replace(router.asPath);
            }
        }
    
        const handleCheckList = async listId => router.push(`/list-items/${listId}`);
     
    
        // New try re
      return (
        <article>
            {props.lists.length > 0 && props.lists.map(list => (
                <div key={list.id}>
                    <div className='flex justify-between my-2 cursor-pointer p-2 items-center'>
                        <p>{ list.title }</p>
                        <div className='flex gap-3'>
                            <AiOutlineDelete size={30} onClick={() => handleDeleteList(list.id)}/>
                            <AiOutlineEye size={30} onClick={() => handleCheckList(list.id)} /> 
                            
                        </div>
                    </div>
                </div>
            ))}
        </article>
      )
    }
    
    export default Lists
    

    我不明白我做错了什么。。。在开发环境中,它工作得很好。。。。

    {/* List is empty and display empty message // Else show list */}
            {props.lists && <Lists lists={props.lists}/>}
            {props.lists.length === 0 && 
            <p className="mt-2 text-2xl font-extralight">No lists created yet.</p>}
          </aside>
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   Rizwan    1 年前

    组件应为 props.lists 作为一个数组,最初看起来像 props.list 没有数组。这就是为什么它会导致错误 props.lists.length ,以及 props.lists.map 仅在以下情况下可用 props.lists(属性列表) 是一个数组。

    所以在调用它之前,请确保 props.list(属性列表) 是一个数组,可以使用可选的链接( props?.lists.?length )