未捕获的类型错误:无法读取 ReactJS 中为 null 的属性“value”
2022-03-02
2227
我正在尝试在React中创建一个通过TMDB API进行搜索的搜索栏,但我遇到了一些问题。每当我输入搜索栏时,我都会出现一个错误,说
无法读取null的属性(读取'value')
,我不确定问题可能是什么以及为什么它以null为单位。我在
941614447
中调用提及。
3个回答
您可以尝试使用
可选链接
(
?.
)
function Search() {
const [searchQuery, setSearchQuery] = useState("");
const [timeoutId, updateTimeoutId] = useState();
const fetchData = async (searchString) => {
const response = await axios.get(`https://api.themoviedb.org/3/search/movie?api_key=f134dfeac1ebb17feefa58d7f94e94cd&language=en-US&query=${searchString}&page=1&include_adult=false`);
console.log(response);
};
const onTextChange = (e) => {
clearTimeout(timeoutId);
setSearchQuery(e.target?.value);
const timeout = setTimeout(() => fetchData(e.target?.value), 500);
updateTimeoutId(timeout);
};
return(
<div>
<SearchBox>
<SearchInput placeholder="SEARCH" value={searchQuery} onChange={onTextChange}></SearchInput>
</SearchBox></div>
);
}
Zach Jensz
2022-03-02
e.target.value
在 Web API 超时返回后不再存在。该函数已结束执行,
e
参数将不再存在。
相反,请在
setTimeout
回调函数中尝试使用
useRef
而不是
e.target.value
,这样当它返回时,它可以引用最新的更改。
类似这样:
function Search() {
const [searchQuery, setSearchQuery] = useState("");
const [timeoutId, updateTimeoutId] = useState();
const query = useRef(searchQuery);
const fetchData = async (searchString) => {
const response = await axios.get(`https://api.themoviedb.org/3/search/movie?api_key=f134dfeac1ebb17feefa58d7f94e94cd&language=en-US&query=${searchString}&page=1&include_adult=false`);
console.log(response);
};
const onTextChange = (e) => {
clearTimeout(timeoutId);
setSearchQuery(e.target.value);
query.current = e.target.value;
const timeout = setTimeout(() => fetchData(query.current), 500);
updateTimeoutId(timeout);
};
return(
<div>
<SearchBox>
<SearchInput placeholder="SEARCH" value={searchQuery} onChange={onTextChange}></SearchInput>
</SearchBox></div>
);
PsiKai
2022-03-02
再次查看您的代码后,我怀疑这是超时回调中的第二次事件访问,此后该事件访问已被取消。您应该在回调范围内保存对事件值的引用,这样就不会对事件对象产生持久的依赖。
const onTextChange = (e) => {
const { value } = e.target;
clearTimeout(timeoutId);
setSearchQuery(value);
const timeout = setTimeout(() => fetchData(value), 500);
updateTimeoutId(timeout);
};
另外,仅供参考,除非您需要
timeoutId
作为状态的一部分来触发重新渲染或其他操作,否则更常见的是在此处使用 React ref 来存储对计时器 ID 的引用。据我所知,您只是在限制
fetchData
调用,无需触发不必要的渲染。
示例:
const timeoutIdRef = useRef();
useEffect(() => {
// clear any running timeouts upon component unmount
return () => clearTimeout(timeoutIdRef.current);
}, []);
...
const onTextChange = (e) => {
const { value } = e.target;
clearTimeout(timeoutIdRef.current);
setSearchQuery(value);
timeoutIdRef.current = setTimeout(() => fetchData(value), 500);
};
Drew Reese
2022-03-02