2

我需要实现一个长列表,长列表中的每一项在onClick的时候都会触发一个新的函数,因为这个函数每次渲染都是不变的,所以我想用useCallback来优化它,这个返回的函数Fn需要通过在参数中,那么我应该使用bind在onClick中传递参数吗?

    const func = useCallback((num) => setIndex(num), [])
    // myComponent
    <TableItem onClick = { func.bind(null, index) } />

这是我的第一个问题,如有错误请见谅,谢谢。

4

2 回答 2

2

如果将回调传递给多个组件,则可以通过以下方式使用 useCallback:

//make Counter a pure component (only re renders if something changed)
const Counter = React.memo(function Counter({
  counter,
  up,
  index,
}) {
  // ok to do onClick={new=>'function'} because we do not pass
  // onClick to sub components unless counter changes
  console.log('rendering index:', index);
  return (
    <button onClick={() => up(index)}>{counter}</button>
  );
});
const App = () => {
  //fixed amount of items that does not re order so can use index
  //  in key, do not use index as key when you don't have fixed
  //  amount of items or re order the list.
  const [counters, setCounters] = React.useState([0, 0]);
  const up = React.useCallback(
    (index) =>
      //pass callback to setCounters so counters is not
      //  a dependency of useCallback
      setCounters((counters) =>
        counters.map((counter, i) =>
          i === index ? counter + 1 : counter
        )
      ),
    []//empty dependency, only created when App mounts
  );
  return (
    <ul>
      {counters.map((counter, index) => (
        <Counter
          up={up}
          counter={counter}
          key={index}
          index={index}
        />
      ))}
    </ul>
  );
};
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>

于 2020-07-17T14:50:48.823 回答
0

您需要在 useCallback 中设置第二个参数,这将防止多次渲染。

即,如果你想在组件启动时设置它,你可以设置

useCallback((num => setIndex(num)), [])

注意[],表示它只会在开头渲染,如果你想在任何变量发生变化时更新它,你可以设置[variablename, ...]

另外,我认为您不需要func.bind,您只能设置

<Component onClick={func}/>

编辑:我误解了这个问题。

如果要在 onClick 中发送参数,可以这样设置

const func = useCallback((num => setIndex(num)), [])
<Component onClick={()=>func(yourParam)}/>

通过这种方式,您的 onClick 将始终使用该功能,但它允许您可以在任何地方设置的参数

于 2020-07-17T14:12:15.720 回答