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.