已编辑代码块以包括来自Accept Answer的控制台日志(log).
我有一个搜索栏组件,我已经将其completely精简为最简单的形式:
import React, { useEffect, useRef, useState } from "react";
import axios from "axios";
const resultTypes = ["categories", "submissions", "users"];
const SearchBar = () => {
const [results, setResults] = useState([]);
const [selectedResultType, setSelectedResultType] = useState(resultTypes[0]);
console.log("render --------");
console.log("selectedResultType: " + selectedResultType);
const selectedResultTypeRef = useRef(null);
console.log(
"selectedResultTypeRef.current: " + selectedResultTypeRef.current
);
const fetchResults = async () => {
console.log("fetching...");
const response = await axios.get(
"https://jsonplaceholder.typicode.com/todos/3"
);
setResults(response.data);
console.log("setResults: ", response.data);
};
useEffect(() => {
console.log("effect 1 ---------");
selectedResultTypeRef.current = selectedResultType;
console.log(
"selectedResultTypeRef.current: " + selectedResultTypeRef.current
);
}, [selectedResultType]);
useEffect(() => {
console.log("effect 2 ---------");
// No need to debounce fetch when changing result type
fetchResults();
}, [selectedResultTypeRef.current]);
return (
<div className="SearchBar__container">
<div className="SearchBarResults__types">
{resultTypes.map((resultType) => (
<button
key={resultType}
onClick={() => {
console.log("click " + resultType + " -------");
setSelectedResultType(resultType);
}}
>
{resultType}
</button>
))}
</div>
</div>
);
};
export default SearchBar;
当我在我的3个按钮(类别、提交和用户)之间单击时,我预计selectedResultType
会改变,然后它会改变selectedResultTypeRef.current
,这样我就可以将其传递到一个备忘的、取消声明的函数中.我删除了所有这些,因为它不相关,但这就是我需要使用引用而不仅仅是组件状态的原因.
这就是我的问题:当我调用异步函数并等待响应以设置结果时,似乎每隔一次单击selectedResultTypeRef.current
就会发生变化(或被识别为变化).我试过了点击这三个按钮的不同组合,每次点击都会触发呼叫fetchResults
的钩子.
Here's the console output using the above code:
Oddly, it fetches twice after missing a fetch for the previous ref change. I really don't know why this is. What's also curious is that when I replace the setResults
line with just a simple console.log(response.data)
, it never misses a hook. Here's the console output from that:
我怀疑setResults
更新以某种方式触发了DOM的重新呈现(即使我在这个简化版本中没有使用results
状态),并且它干扰了selectedResultTypeRef
被识别为被useEffect
钩子捕获的更新.我不知道为什么它每隔一次就更新一次,但我至少已经验证了它的一致模式.
除此之外,我完全不知所措.我不知道还能试什么.