在循环内使用参数对钩子useCallback进行反应

我正在尝试了解钩子功能,但是我似乎还不太清楚如何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是通过相同功能的实例,以优化的组件(例如,PureComponentReact.memo源化组分),以避免不必要的重新渲染。

在这种情况下(或大多数情况下,我怀疑),您不需要处理优化的组件,因此没有足够的理由来记住类似with的回调useCallback


但是,假设备忘录很重要,这里最好的解决方案可能是使用单个函数而不是五个函数:不是每个按钮都带有keyby闭包的唯一函数,而是可以将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>

也许在某些情况下这很有用,但在这种情况下,我要么不理会它(而不用担心优化问题),要么对每个按钮使用单个处理程序。

以上是 在循环内使用参数对钩子useCallback进行反应 的全部内容, 来源链接: utcz.com/qa/403172.html

回到顶部