请考虑以下示例:
<div class="form-group" *ngFor="let todo of toDos; let i = index">
<ul>
<input class="form-control" name="toDo" [(ngModel)]="toDos[i]" placeholder="To Do" style="border:none;">
</ul>
</div>
我只想在安装时使用这种效果,仅此而已,我不在乎toDos
或const userRole = sessionStorage.getItem('role');
const { data, setData, type, setTableType } = useTable([]);
useEffect(() => {
const getData = async () => {
// fetch some data from API
const fetchedData = await axios('..');
if (userRole === 'admin') {
setData([...fetchedData, { orders: [] }]);
} else {
setData(fetchedData);
}
if (type === 1') {
setTableType('normal');
}
};
getData();
}, []);
是否已更改!
所以,现在我的问题是:
userRole
在
依赖数组?它甚至都不是状态!setData
在依赖项数组中丢失
不是总是相同的参考还是会改变?userRole
行?还是这绝对是野蛮的?编辑:
让我重新表述一个问题:如果这些变量发生变化并且我不在乎它们的新值怎么办?尤其是当setData
在同一文件中的不同位置进行更新时。我只想读取初始值并运行一次useEffect,如何实现该目标?
反响/详尽下降警告
答案 0 :(得分:3)
useEffect
中,因此是一个依赖项(如果它将更改-useEffect
无效)useEffect
不知道它是否相同,这就是为什么它要求依赖项const userRole = sessionStorage.getItem('role');
const { data, setData } = useTable([]);
useEffect(() => {
const getData = async () => {
// fetch some data from API
const fetchedData = await axios('..');
if (userRole === 'admin') {
setData([...fetchedData, { orders: [] }]);
} else {
setData(fetchedData);
}
};
getData();
}, [userRole, setData]);
“但是我只想在挂载上运行它!”,您会说。现在,请记住:如果指定deps,则该效果所使用的组件内部的所有值都必须存在。包括道具,状态,功能-组件中的任何内容。
答案 1 :(得分:0)
Linting是分析代码中潜在错误的过程。现在,当我们谈论为什么会出现棉绒错误时,我们需要了解规则是通过牢记特定功能的理想用例来设置的。
在使用useEffect钩子的情况下,一般的概念是说,如果我们有一个可能更改或可能导致逻辑流更改的值,则所有这些值都应放入依赖关系数组。
因此,数据是第一个进入的候选对象。与userRole相似,因为它被用于控制逻辑流而不是简单地作为值。
我建议采用短绒棉布的建议来忽略该错误。
答案 2 :(得分:0)
注意事项:我不建议实际使用它。这实现了错误的逻辑,并且保证在值更改时是错误的。 linter试图提供帮助,因为下面的代码引入了许多细微的错误。
但是,如果要执行此操作,则可以使用ref
来存储一次性功能:
@GET("/database/search")
Call<List<Result>> getSongsExampleInfo(@Query("per_page") Integer per_page, @Query("page") Integer page, @Query("genre") String genre, @Query("key") String key, @Query("secret") String secret);
答案 3 :(得分:0)
编辑:更新 React 后,Eslint 似乎开始抱怨以下解决方案,所以我可能会使用 // eslint-disable-line
您是正确的,如果您希望效果在组件安装时仅运行一次,则为 useEffect
提供一个空的依赖项数组是一种可行的方法。 ESLint 警告您的问题是效果可能使用陈旧数据执行,因为它引用外部状态属性,但正如您所注意到的,为数组提供它要求的依赖项会导致效果在任何时候运行它们也会发生变化。
幸运的是,我很惊讶还没有提到一个简单的解决方案 - 将效果包装在 useCallback
中。您可以安全地将依赖项赋予 useCallback
,而无需再次执行。
// Some state value
const [state, setState] = useState();
const init = useCallback(
() => {
// Do something which references the state
if (state === null) {}
},
// Pass the dependency to the array as normal
[state]
);
// Now do the effect without any dependencies
useEffect(init, []);
现在 init
会在依赖项更改时重新记忆,但除非您在其他地方调用它,否则实际上只会在下面的 useEffect
中调用它来执行。
回答您的具体问题:
userRole
是因为 React 组件在每次渲染时都会重新运行,这意味着 userRole
将来可能会有不同的值。您可以通过将 userRole
移到您的函数之外来避免这种情况。setData
可能实际上总是相同的,但它存在改变的可能性,这就是为什么 ESLint 希望您将其作为依赖项包含在内。由于它是自定义钩子的一部分,因此不能将其移出您的函数,您可能应该将其包含在依赖项数组中。