我在 React 组件中有以下用例。
这是一个使用 React Autosuggest 的搜索用户输入。 .它的值始终是一个 ID,所以我只有用户 ID 作为 Prop 。因此,在第一次加载以显示用户名值时,我需要在第一次安装时获取它。
编辑:我不想在以后更改时再次获取该值,因为我已经从我的建议请求中获得了该值。
type InputUserProps = {
userID?: string;
onChange: (userID: string) => void;
};
// Input User is a controlled input
const InputUser: React.FC<InputUserProps> = (props) => {
const [username, setUsername] = useState<string | null>(null);
useEffect(() => {
if (props.userID && !username) {
fetchUsername(props.userID).then((username) => setUsername(username));
}
}, []);
async function loadSuggestions(inputValue: string): Suggestion[] {
return fetchSuggestions(inputValue);
}
function selectSuggestion(suggestion: Suggestion): void {
props.onChange(suggestion.userID); // I don't want to rerun the effect from that change...
setUsername(suggestion.username); // ...because I set the username here
}
return (
<InputSuggest
value={props.userID}
label={username}
onSuggestionsRequested={loadSuggestions}
onSuggestionSelected={selectSuggestion}
/>
);
};
export default InputUser;
(我正在添加一个简化的方式来调用这个组件)const App: React.FC<AppProps> = (props) => {
// simplified, I use react-hook-form in the real code
const [userID, setUserID] = useState<string?>(any_initial_value_or_null);
return <InputUser userID={userID} onChange={(newValue)=>setUserID(newValue)} />
};
export default App;
它有效,但我的 useEffect 钩子(Hook)上有以下警告React Hook useEffect has missing dependencies: 'props.userID' and 'username'. Either include them or remove the dependency array.eslint(react-hooks/exhaustive-deps)
但是如果我这样做,我会运行它不止一次,因为用户名值是由钩子(Hook)本身更改的!由于它在没有所有依赖项的情况下工作,我想知道:最佳答案
看起来像 userId
确实应该是一个依赖项,因为如果它发生变化,你想再次运行你的查询。
我认为您可以放弃对 username
的检查。并且总是在且仅当 userId
变化:
useEffect(() => {
if(props.userID) {
fetchUsername(props.userID)
.then((username) => setUsername(username))
}
}, [props.userID])
一般来说,您希望列出效果中的所有闭包变量,以避免执行效果时过时的引用。- 编辑以解决 OP 问题:
因为在您的用例中,您知道您只想在初始挂载上执行操作,传递一个空的依赖数组是一种有效的方法。
另一种选择是跟踪获取的用户 ID,例如
const fetchedIds = useRef(new Set())
每当您获取新 ID 的用户名时,您都可以更新引用:fetchedIds.current.add(newId)
在您的效果中,您可以测试:if (props.userID && !fetchedIds.current.has(props.userID)) {
// do the fetch
}
关于javascript - react 钩子(Hook) : why does useEffect need an exhaustive array of dependencies?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63216143/