简体   繁体   中英

TypeError: undefined is not an object (evaluating 'results.length') in Search Component

Working on a search component that returns a list of results from the /api/nextSearch.tsx but when entering a query into the input box I get TypeError: undefined is not an object (evaluating 'results.length') every time.

Feels like I'm either misunderstanding some fundamental logic or overlooked something so simple I can't see it.

/component/search.js

import { useCallback, useRef, useState } from "react";
import Link from "next/link";

export default function Search() {
  const searchRef = useRef(null);
  const [query, setQuery] = useState("");
  const [active, setActive] = useState(false);
  const [results, setResults] = useState([]);

  const searchEndpoint = (query) => `/api/nextSearch?searchString=${query}`;

  const onChange = useCallback((event) => {
    const query = event.target.value;
    setQuery(query);
    console.log("Set onChange");

    fetch(searchEndpoint(query))
      .then((res) => res.json())
      .then((res) => {
        setResults(res.results);
      });
  }, []);

  const onFocus = useCallback(() => {
    setActive(true);
    window.addEventListener("click", onClick);
    console.log("Set onFocus");
  }, []);

  const onClick = useCallback((event) => {
    if (searchRef.current && !searchRef.current.contains(event.target)) {
      setActive(false);
      window.removeEventListener("click", onClick);
    }
  }, []);

  return (
    <div ref={searchRef}>
      <input
        onChange={onChange}
        onFocus={onFocus}
        placeholder="Search posts"
        type="text"
        value={query}
      />
      {active && results.length > 0 && (
        <ul className="">
          {results.map(({ id, title }) => (
            <li className="" key={id}>
              <Link href="/posts/[id]" as={`/posts/${id}`}>
                <a>{title}</a>
              </Link>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

/api/nextSearch.js

import type { NextApiRequest, NextApiResponse } from "next";
import prisma from "../../lib/prisma";

type Data = {
  results: string[];
};

export default async function handle(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { searchString } = req.query;
  const searchData = await prisma.term.findMany({
    where: {
      title: {
        search: searchString,
      },
    },
  });


  res.json(searchData);
}

In line 15, it seems res.results is undefined

fetch(searchEndpoint(query))
   .then((res) => res.json())
   .then((res) => {
     setResults(res.results);
   });

In your next.js app, you had defined a type Data with results but it is not utilised when you call res.json(searchData) .

Is searchData supposed to be an array of string, ie string[] ? Would this resolve your problem?

return res.json({
   results: searchData
});

You can also fix this:

{active && results.length > 0 && (

to

{active && results && results.length > 0 && (

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM