You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React搜索问题:未搜索时提前显示无结果页面如何修复

问题描述

开发带电影搜索功能的React页面时,遇到NotFoundPage组件在未执行搜索操作前就显示“无结果”提示的问题。希望仅在执行搜索后未找到结果时才展示该组件,求错误原因及修复方法。

现有代码

MoviesPage组件

import { useState, lazy, useEffect } from 'react';
import * as movieAPI from '../../../services/movie-api';
import { Gallery } from 'components/Gallery/Gallery';

import { SearchForm, Button, Label, Input } from './MoviesPage.styled';
import { useSearchParams, useLocation } from 'react-router-dom';

const NotFoundPage = lazy(() => import('../NotFound/NotFoundPage.js'));

export default function MoviesPage() {
  const [searchQuery, setSearchQuery] = useState('');
  const [data, setData] = useState(null);
  // eslint-disable-next-line no-unused-vars
  let [_, setSearchParams] = useSearchParams();
  const handleInputChange = e => {
    setSearchQuery(e.currentTarget.value);
  };
  const { search } = useLocation();

  useEffect(() => {
    if (!search) {
      return;
    }
    movieAPI.fetchSearch(search.slice(7)).then(setData);
  }, [search]);

  const handleSubmit = e => {
    e.preventDefault();
    const normalizeSearchQuery = searchQuery.trim().toLowerCase();
    if (!normalizeSearchQuery) {
      return;
    }
    movieAPI.fetchSearch(normalizeSearchQuery).then(setData);
    setSearchParams(`query=${normalizeSearchQuery}`);
    // setSearchQuery('');
  };

  return (
    <>
      <SearchForm onSubmit={handleSubmit}>
        <Input
          type="text"
          name="searchQuery"
          autoComplete="off"
          autoFocus
          placeholder="Search movies"
          value={searchQuery}
          onChange={handleInputChange}
        />
        <Button type="submit">
          <Label>Search</Label>
        </Button>
      </SearchForm>

           {data?.results.length > 0 ? <Gallery data={data} /> : <NotFoundPage />}
    </>
  );
}

NotFoundPage组件

import { Link } from 'react-router-dom';

function NotFoundPage() {
  return (
    <div>
      <h2> Results not found :(</h2>
      <p>
        <Link to="/">Back</Link>
      </p>
    </div>
  );
}

export default NotFoundPage;

错误原因

初始状态下data为null,页面首次渲染时data?.results.length > 0的判断结果为false(data为null时,data?.results是undefined,不存在length属性,整个表达式逻辑为假),因此会直接渲染NotFoundPage组件。

修复方案

新增一个状态标记是否已执行过搜索操作,只有当搜索执行后,才根据结果判断是否展示NotFoundPage。

修改后的MoviesPage组件代码

import { useState, lazy, useEffect } from 'react';
import * as movieAPI from '../../../services/movie-api';
import { Gallery } from 'components/Gallery/Gallery';

import { SearchForm, Button, Label, Input } from './MoviesPage.styled';
import { useSearchParams, useLocation } from 'react-router-dom';

const NotFoundPage = lazy(() => import('../NotFound/NotFoundPage.js'));

export default function MoviesPage() {
  const [searchQuery, setSearchQuery] = useState('');
  const [data, setData] = useState(null);
  const [isSearched, setIsSearched] = useState(false); // 新增:标记是否已执行搜索
  let [_, setSearchParams] = useSearchParams();
  const handleInputChange = e => {
    setSearchQuery(e.currentTarget.value);
  };
  const { search } = useLocation();

  useEffect(() => {
    if (!search) {
      setIsSearched(false); // 无搜索参数时重置搜索状态
      return;
    }
    movieAPI.fetchSearch(search.slice(7)).then(res => {
      setData(res);
      setIsSearched(true); // URL参数触发搜索后标记为已搜索
    });
  }, [search]);

  const handleSubmit = e => {
    e.preventDefault();
    const normalizeSearchQuery = searchQuery.trim().toLowerCase();
    if (!normalizeSearchQuery) {
      return;
    }
    setIsSearched(true); // 点击搜索按钮后标记为已搜索
    movieAPI.fetchSearch(normalizeSearchQuery).then(setData);
    setSearchParams(`query=${normalizeSearchQuery}`);
    // setSearchQuery('');
  };

  return (
    <>
      <SearchForm onSubmit={handleSubmit}>
        <Input
          type="text"
          name="searchQuery"
          autoComplete="off"
          autoFocus
          placeholder="Search movies"
          value={searchQuery}
          onChange={handleInputChange}
        />
        <Button type="submit">
          <Label>Search</Label>
        </Button>
      </SearchForm>

      {/* 仅在已搜索时,根据结果展示对应组件 */}
      {isSearched ? (
        data?.results.length > 0 ? <Gallery data={data} /> : <NotFoundPage />
      ) : null}
    </>
  );
}

修复逻辑说明

  1. 新增isSearched状态,初始值为false,表示未执行过搜索
  2. 点击搜索按钮或通过URL参数触发搜索时,将isSearched设为true
  3. 渲染阶段:只有isSearched为true时,才根据搜索结果展示Gallery或NotFoundPage;未搜索时不渲染任何结果相关组件
  4. 当URL无搜索参数时(比如首次进入页面),重置isSearched为false,避免残留状态影响显示

内容的提问来源于stack exchange,提问作者nika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:10:32