React电影网站报setQuery is not a function错误排查
React电影网站搜索功能报错排查与修复
问题表现
- 项目为支持电影搜索、影片全量详情查看的React站点,预设默认搜索关键词为 pushpa
- 异常现象:
- 搜索输入框未展示默认搜索值,但
query状态本身运行逻辑正常,直接修改query状态初始值可正常生效 - 在搜索框输入内容调用
setQuery方法时触发报错,控制台抛出错误:Search.jsx:13 Uncaught TypeError: setQuery is not a function at onChange (Search.jsx:13:1)
- 搜索输入框未展示默认搜索值,但
问题根因
一共3处问题,直接触发报错的是第一点:
- Context传值遗漏:
AppContext.Provider的value配置中,仅暴露了isLoading、isError、movie三个状态,没有把定义好的query状态和setQuery更新方法传递给上下文。子组件从Context解构获取的query、setQuery实际值为undefined,一方面输入框绑定value时拿不到默认的"pushpa"值,另一方面调用undefined自然会抛出"不是函数"的类型错误。 - 搜索请求逻辑缺陷:拉取电影数据的
useEffect依赖数组为空,仅会在组件首次挂载时执行一次,后续搜索关键词变化时不会自动触发新的搜索请求,搜索功能实际无法生效。 - 自定义Hook冗余传参:封装的
useGlobalContext已经内部调用useContext(AppContext)完成上下文读取,组件使用时不需要额外传入AppContext参数,属于无效写法。
修复步骤
1. 修改context.js代码
- 调整Context.Provider的value属性,补全暴露
query和setQuery - 将
query加入数据请求useEffect的依赖数组,实现关键词变化自动重新拉取数据 - 同步修正原代码中OMDB接口返回字段名错误、加载态/错误态未重置的隐性问题
修正后完整代码:
import React, { useEffect, createContext, useState } from "react"; const API_URL = `http://www.omdbapi.com/?apikey=APIKEY`; const AppContext = createContext(); const AppProvider = ({ children }) => { const [isLoading, setIsLoading] = useState(true); const [movie, setMovie] = useState([]); const [isError, setIsError] = useState({ show: false, msg: "" }); const [query, setQuery] = useState("pushpa"); const getMovies = async (url) => { setIsLoading(true); try { const res = await fetch(url); const data = await res.json(); console.log(data); if (data.Response === "True") { setIsLoading(false); setMovie(data.Search); setIsError({show: false, msg: ""}) } else { setIsLoading(false); setIsError({ show: true, msg: data.Error, }); } } catch (error) { setIsLoading(false); console.log(`An Error Occurred: ${error.message}`); } }; useEffect(() => { getMovies(`${API_URL}&s=${query}`); }, [query]); return ( <AppContext.Provider value={{isLoading, isError, movie, query, setQuery}}> {children} </AppContext.Provider> ); }; const useGlobalContext = () => { return React.useContext(AppContext); }; export { AppContext, AppProvider, useGlobalContext };
2. 修改Search.js代码
移除useGlobalContext调用时传入的冗余AppContext参数,修正后完整代码:
import React from 'react'; import { useGlobalContext } from './context'; const Search = () => { const { query, setQuery, isError } = useGlobalContext(); return ( <> <section id="search-section"> <h2>Search Your Favourite Movie</h2> <form action="#" onSubmit={(e) => {e.preventDefault()}}> <input type="text" placeholder="Search Here" value={query} onChange={(e) => setQuery(e.target.value)} /> </form> <div className="card-error"> <p>{isError.show && isError.msg}</p> </div> </section> </> ) } export default Search;
修复后验证
- 页面首次加载时,搜索输入框自动展示默认值pushpa,同时自动拉取该关键词对应的电影列表
- 在搜索框输入内容时控制台无报错,关键词变化后自动触发对应内容的电影搜索
- 搜索无结果时正常展示错误提示,搜索成功时错误提示自动消失
内容的提问来源于stack exchange,提问作者Agrim Singh
相关产品推荐
相关产品推荐

