【发布时间】:2020-11-22 17:38:57
【问题描述】:
我在 React 组件中有以下用例。
这是一个使用React Autosuggest 的搜索用户输入。它的值始终是一个 ID,所以我只有用户 ID 作为道具。因此,在第一次加载以显示用户名值时,我需要在第一次加载时获取它。
编辑:我不想在以后更改时再次获取该值,因为我已经从我的建议请求中获得了该值。
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 钩子上有以下警告
React Hook useEffect has missing dependencies: 'props.userID' and 'username'. Either include them or remove the dependency array.eslint(react-hooks/exhaustive-deps)
但如果我这样做,我会运行它不止一次,因为用户名值是由钩子本身更改的!由于它在没有所有依赖项的情况下工作,我想知道:
- 如何彻底解决我的案件?
- 这些依赖项的用途是什么?为什么建议将它们详尽无遗?
【问题讨论】:
-
我不想从该更改中重新运行效果 - 如果我理解您更新的问题,您希望效果只运行一次,因此使用空数组是美好的。或者,您可以将所有依赖项包含到
useEffect的依赖项数组中,但仅使用在useEffect至少执行一次后评估为 false 的条件在初始渲染时获取用户。 -
是的,我仍然收到这个 eslint 警告。但我想这只是一个过于激进的规则,我应该禁用它。
React Hook useEffect has missing dependencies: 'props.userID' and 'username'. Either include them or remove the dependency array.eslint(react-hooks/exhaustive-deps) -
由于我的回答和链接文章中提到的原因,我建议不要禁用此规则。仅在某些特定情况下(例如您的情况)才可以对依赖项撒谎,但通常您应该在依赖项数组中包含效果的所有依赖项。如果可以的话,还请尝试改进您的应用程序的设计,以避免一开始就必须这样做。
-
useEffectdep 的数组与useCallback和useMemo等其他钩子不同,如果不包含每个 dep,可能会导致值过时。useEffect更多地依赖于业务逻辑,因此 imo 一个 linter 不应该决定您的业务逻辑。大多数情况下,如果可能,我通常会列出所有的部门,否则我会忽略该场景的规则并就原因发表评论。eslint-disable-next-line react-hooks/exhaustive-deps
标签: javascript reactjs typescript react-hooks