我正在尝试了解钩子功能,但是我似乎还不太清楚如何useCallback
正确使用该函数。据我从有关钩子的规则中了解到的,我应该将它们称为顶级,而不是在逻辑(如循环)之内。这让我很困惑,应该如何useCallback
在从循环渲染的组件上实现。
看一下下面的示例代码片段,在该代码片段中,我创建了5个带有onClick
处理程序的按钮,该处理程序将按钮的编号输出到控制台。
const Example = (props) => {
const onClick = (key) => {
console.log("You clicked: ", key);
};
return(
<div>
{
_.times(5, (key) => {
return (
<button onClick={() => onClick(key)}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>
现在,由于我在中使用arrow函数<button onClick={() => onClick(key)}>
,因此每次在Example呈现时都会创建一个新的函数实例,这是因为我希望onClick
函数知道哪个按钮调用了它。我以为可以通过使用来使用新的react
hooks功能来防止这种情况useCallback
,但是如果我将其应用于,const onClick
那么它仍然会为每个渲染创建一个新实例,这是因为需要给定key
参数的内联箭头功能,所以我不允许据我所知将其应用于循环中的渲染(尤其是如果循环顺序可能会改变吗?)。
那么useCallback
,在保持相同功能的情况下,我将如何在这种情况下实施呢?有可能吗?
这里的简单答案是,您可能不应该useCallback
在这里使用。点useCallback
是通过相同功能的实例,以优化的组件(例如,PureComponent
或React.memo
源化组分),以避免不必要的重新渲染。
在这种情况下(或大多数情况下,我怀疑),您不需要处理优化的组件,因此没有足够的理由来记住类似with的回调useCallback
。
但是,假设备忘录很重要,这里最好的解决方案可能是使用单个函数而不是五个函数:不是每个按钮都带有key
by闭包的唯一函数,而是可以将by附加key
到元素上:
<button data-key={key}>{key}</button>
然后从event.target.dataset["key"]
内部单击处理程序读取密钥:
const Example = (props) => {
// Single callback, shared by all buttons
const onClick = React.useCallback((e) => {
// Check which button was clicked
const key = e.target.dataset["key"]
console.log("You clicked: ", key);
}, [/* dependencies */]);
return(
<div>
{
_.times(5, (key) => {
return (
<button data-key={key} onClick={onClick}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>
综上所述,可以在一个钩子中记住多个功能。 useCallback(fn, deps)
等同于useMemo(() => fn, deps)
,useMemo
可用于一次记忆多个功能:
const clickHandlers = useMemo(() => _.times(5, key =>
() => console.log("You clicked", key)
), [/* dependencies */]);
const Example = (props) => {
const clickHandlers = React.useMemo(() => _.times(5, key =>
() => console.log("You clicked", key)
), [/* dependencies */])
return(
<div>
{
_.times(5, (key) => {
return (
<button onClick={clickHandlers[key]}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>
也许在某些情况下这很有用,但在这种情况下,我要么不理会它(而不用担心优化问题),要么对每个按钮使用单个处理程序。
我试图了解钩子的功能,但是我似乎不太明白应该如何正确地使用函数。根据我对钩子规则的理解,我应该称它们为顶级的,而不是逻辑内的(比如循环)。这让我很困惑,我应该如何在从循环呈现的组件上实现。 请看下面的示例片段,其中我使用处理程序创建了5个按钮,该处理程序将按钮的编号打印到控制台。 现在,由于我在中使用了箭头函数,每次呈现示例时都会创建一个新的函数实例,我这样做是因为我希望函数知道是哪个按钮调用了它
问题内容: 随着React 中钩子的引入,现在的主要困惑是何时将函数组件与钩子和类组件一起使用,因为在钩子的帮助下,甚至可以在函数组件中获得和部分使用。所以,我有以下问题 钩子的真正优点是什么? 何时使用带有钩子的函数组件和类组件? 例如,带有钩子的功能组件不能像类组件那样帮助性能。他们没有执行就不能跳过重新渲染。还有其他原因吗? 提前致谢。 问题答案: 引入和其他特性(例如和)的思想是帮助减少必
CodeSandBox:https://codesandbox.io/embed/react-table-editable-content-ggvcy 当试图处理React表中的输入时,我的输入失去焦点,因此一次只能键入1个字符。 如何修复我的渲染周期,以允许输入? 编辑:我不小心用工作版本的代码更新了沙盒,尽管它还有另一个bug:如何在刷新更新期间捕获由于焦点模糊更改而导致的react事件?
我无法理解为什么我的AppReact组件呈现两次,如下面的gif所示。 我插入了一个控制台。在返回组件之前记录日志,查看组件渲染的次数。 每当我移除useState钩子时,我的应用程序只会呈现一次我认为应该呈现的效果。任何关于为什么会发生这种情况的指导都是受欢迎的
问题内容: 我在名为data的变量中返回了以下JSON。 这是GETS返回的JSON … 我试图使用$ .each遍历整个集合,但是遇到了警报显示未定义的问题。我尝试了很多不同的语法,但似乎无法弄清楚。 我正在使用的jQuery是 谁能指出我正确的方向? 编辑 这是我用来获取数据的代码 这是在回调时被调用的函数 编辑2 这有点使我感到困惑,根据文档,它应该可以正常使用,但事实并非如此。据提琴手说,
我目前正在构建一个动态表单引擎,希望在呈现应答摘要组件时显示redux存储区的结果。我认为最好的方法是在加载answerSummary组件后设置“complete”状态并将其设置为true,但在map函数中这样做不起作用,并抛出无限循环react错误。 代码如下: 编辑:我知道你不能在渲染中设置状态-我这样写是为了尝试和传达我想要做的事情