使用效果钩中的问题
假设我有一个称为 count 的状态。
const [count, setCount] = useState();
现在,假设我想增加 count ,每次按下键盘中的某些键时。
因此,我可以使用使用效果挂钩并添加事件侦听器。
useEffect(() => {
document.addEventListener("keydown", increaseCount);
}, []);
功能增加了,增加了计数,其中1
const increaseCount = () => {
setCount(prevCount => prevCount + 1);
};
井都奏效了。 ,但是,如果我想在增加估计中获得 count 的当前值,我将无法做到!事件侦听器仅在组件安装时一次调用一次(因为使用效果具有空的依赖关系数组)。
如果我将 count 添加到依赖项数组中,我有一个新问题 - 我正在创建一种循环,因为使用效率会调用fightecount,它将调用setCount(),这将导致组件重新渲染,这将再次调用使用效果,依此类推。
我在目前正在从事的一些项目上遇到了这种问题,这非常令人沮丧。因此,如果您知道如何回答 - 谢谢! :)
摘要
使用空的依赖项数组和登录计数在增加量, count 将始终为0:
// Get a hook function
const {useState, useEffect} = React;
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.addEventListener("keydown", increaseCount);
}, []);
const increaseCount = () => {
setCount((prevCount) => prevCount + 1);
console.log(count);
};
return (
<div>
count = {count}
</div>
);
};
// Render it
ReactDOM.render(
<Counter />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
当将 count 添加到依赖项数组中时,我们会看到这种“循环”发生的事情:
// Get a hook function
const {useState, useEffect} = React;
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.addEventListener("keydown", increaseCount);
}, [count]);
const increaseCount = () => {
setCount((prevCount) => prevCount + 1);
console.log(count);
};
return (
<div>
count = {count}
</div>
);
};
// Render it
ReactDOM.render(
<Counter />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Let's say I have a state called count.
const [count, setCount] = useState();
Now let's say I would like to increase count with 1 every time some key in the keyboard is being pressed.
So I can use useEffect hook and add an event listener to it.
useEffect(() => {
document.addEventListener("keydown", increaseCount);
}, []);
The function increaseCount, increasing count with 1
const increaseCount = () => {
setCount(prevCount => prevCount + 1);
};
Well everything is working great. BUT, if I want to get the current value of count inside increaseCount, I can't do this! The event listener is only called once when the component is mounting (because the useEffect has an empty dependency array).
And if I add count to the dependency array, I have a new problem - I'm creating a kind of loop, because useEffect will call increaseCount, that will call setCount(), that will cause the component to re-render, which will call useEffect again and so on and so on.
I have this kind of problem on a few projects I'm currently working on, and it is very frustrating. So if you know how to answer this - thanks! :)
snippets
When using an empty dependency array and login count inside increaseCount, count will always be 0:
// Get a hook function
const {useState, useEffect} = React;
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.addEventListener("keydown", increaseCount);
}, []);
const increaseCount = () => {
setCount((prevCount) => prevCount + 1);
console.log(count);
};
return (
<div>
count = {count}
</div>
);
};
// Render it
ReactDOM.render(
<Counter />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
and when adding count to the dependency array, we see this "loop" thing happening:
// Get a hook function
const {useState, useEffect} = React;
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.addEventListener("keydown", increaseCount);
}, [count]);
const increaseCount = () => {
setCount((prevCount) => prevCount + 1);
console.log(count);
};
return (
<div>
count = {count}
</div>
);
};
// Render it
ReactDOM.render(
<Counter />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的应该做的事情确实取决于您需要做什么。参见 xy问题。
如前所述,您正在尝试多种用例。
至于您特别提到的情况,这里有一个解决方案。
您可以正常从数组长度获得“当前索引”,这就是我在这里做的。
如果“ currentIndex”比那更复杂,并且与数组状态不可分割地捆绑在一起,则应
用户educer
以纯粹的方式设置捆绑状态。您也可以使用对侦听器函数中数组的引用。
用户使用方法:
由于我没有足够的详细信息,因此在还原器中,这与上述解决方案相同。
What you should do really depends on what you need to do. See X Y problem.
As mentioned there are multiple use cases you are trying for.
As for the situation you mentioned in particular, here's one solution.
You can get the "current Index" from the array length normally, which is what I'm doing here.
If the "currentIndex" is more complicated than that and inexorably tied together with the array state, you should
useReducer
to set up that tied state in a pure fashion.You could also use a reference to the array in your listener function.
useReducer Approach:
As I don't have enough details, this is the same solution as above, just in a reducer.