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

如何使用React Hook useEffect实现含searchMovies的搜索栏功能?

基于React useEffect实现电影/演员搜索栏的修正方案与技巧

先修正现有代码的明显错误

1. 状态定义错误修正

你的actorSearch状态类型声明错误,ActorAttributes是单个演员对象,搜索结果应为数组;同时searching状态未定义,建议把search改名为isLoading更语义化:

const Home: React.FC = () => {
    const [isLoading, setIsLoading] = React.useState(false);
    const [searchQuery, setSearchQuery] = React.useState(""); // 新增搜索关键词状态
    const [movieSearch, setMovieSearch] = React.useState<MovieAttributes[]>([]);
    const [actorSearch, setActorSearch] = React.useState<ActorAttributes[]>([]); // 修正为数组类型

2. 异步函数错误修正

demo函数里的demoDistrictSearch未定义,推测是笔误应该用movieSearch;同时setSearching需改为setIsLoading,并添加错误处理:

const fetchSearchResults = async (query: string) => {
    if (!query.trim()) {
        // 空关键词时清空结果
        setMovieSearch([]);
        setActorSearch([]);
        return;
    }
    setIsLoading(true);
    try {
        // 先请求电影
        const movieResults = await searchMovies(query);
        setMovieSearch(movieResults);
        
        // 确保电影结果存在时再请求演员
        if (movieResults.length > 0) {
            const actorResults = await searchActors(query, movieResults[0].SID);
            setActorSearch(actorResults);
        }
    } catch (err) {
        console.error("搜索出错:", err);
        // 可新增error状态展示错误提示
    } finally {
        setIsLoading(false);
    }
};

3. 正确使用useEffect触发搜索

  • 组件挂载时执行一次默认搜索:
React.useEffect(() => {
    fetchSearchResults("Dumbo");
}, []);
  • 根据用户输入实时搜索(带防抖避免频繁请求):
React.useEffect(() => {
    const timer = setTimeout(() => {
        fetchSearchResults(searchQuery);
    }, 300); // 300ms延迟,用户停止输入后再发起请求
    
    return () => clearTimeout(timer); // 清理定时器,避免无效请求
}, [searchQuery]);

4. 添加搜索输入UI

绑定输入框到searchQuery状态,展示搜索结果:

return (
    <div>
        <input
            type="text"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder="搜索电影或演员..."
            disabled={isLoading}
        />
        {isLoading && <p>搜索中...</p>}
        
        <h3>电影结果</h3>
        <ul>
            {movieSearch.map(movie => (
                <li key={movie.OBJECTID}>
                    <h4>{movie.NAME}</h4>
                    <p>导演: {movie.DIRECTOR}</p>
                    <p>{movie.DESCRIP}</p>
                </li>
            ))}
        </ul>
        
        <h3>演员结果</h3>
        <ul>
            {actorSearch.map((actor, index) => (
                <li key={index}>
                    <p>{actor.NAME} ({actor.TYPE})</p>
                </li>
            ))}
        </ul>
    </div>
);

实用技巧与建议

  • 异步请求清理:如果接口支持AbortController,可在useEffect清理函数中取消请求,避免组件卸载后更新状态导致内存泄漏:
    React.useEffect(() => {
        const abortController = new AbortController();
        
        const fetchData = async () => {
            try {
                const movieResults = await searchMovies(searchQuery, { signal: abortController.signal });
                // 后续逻辑
            } catch (err) {
                if (err instanceof DOMException && err.name === "AbortError") return;
                console.error(err);
            }
        };
        
        fetchData();
        return () => abortController.abort();
    }, [searchQuery]);
    
  • 状态语义化:用isLoading代替模糊的search命名,让状态用途更清晰。
  • 空值防御:使用数组元素前先判断长度,避免Cannot read property 'SID' of undefined这类错误。
  • 错误处理:异步请求必须加try/catch,可新增error状态展示友好的错误提示。
  • 类型严格性:给searchMovies/searchActors函数添加返回值类型,确保TypeScript类型校验生效,减少运行时错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 16:05:32