React useCallback钩子用于地图渲染

时间:2019-05-03 05:48:24

标签: reactjs react-hooks usecallback

当将回调传递给组件时,我应该使用useCallback钩子返回一个已记忆的回调(以防止不必要的渲染):

import doSomething from "./doSomething";
const FrequentlyRerenders = ({ id }) => {
  const onEvent = useCallback(() => doSomething(id), [id]);
  return (
    <ExpensiveComponent onEvent={ onEvent } />
  );
};

但是,如果我使用地图怎么办?例如:

import doSomething from "./doSomething";
const FrequentlyRerendersMap = ({ ids }) => {
  return ids.map(id => {
    const onEvent = useCallback(() => doSomething(id), [id]);
    return (
      <ExpensiveComponent key={id} onEvent={ onEvent } />
    );
  });
};

我应该如何正确使用useCallback?上面是传递多个回调的正确方法吗?真的有用吗,并且知道根据数组的一项记忆每个回调吗?

3 个答案:

答案 0 :(得分:0)

将返回的映射的JSX转换为组件,然后可以使用Callback而不会出现问题

import doSomething from "./doSomething";
const MappedComponent =(props) => {
   const onEvent = useCallback(() => doSomething(props.id), []);
   return (
      <ExpensiveComponent onEvent={ onEvent } />
   );
}

const FrequentlyRerendersMap = ({ ids }) => {
  return ids.map(id => {
    return <MappedComponent key={id} id={id} />
  });
};

答案 1 :(得分:0)

重新架构师的答案已经绕开了IMO问题。不过,我认为创建一个新组件可能是一个好主意。

但是要回答这个问题,您的代码:

const http = new XMLHttpRequest();
const url = 'http://192.168.1.10/';
http.open('get', url, false);
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onload = function () {
    if(http.status === 200 || http.status == 0) {
         alert("succeed")
    } else {
          alert("failed")
    }
}
http.send();

实际上是您想要在地图上记住的内容。我不知道useCallback的实现,但是它应该增加很少的内存开销。一个stackFrame,以及它们为将数组简化为用于记忆功能的某种键所做的一切。

除非您要处理大量元素,否则EG会对虚拟化组件进行无限滚动,因此实际上可以安全地使用Callback。实际上,小的内存开销可能比重新呈现所有这些组件便宜得多。

答案 2 :(得分:0)

另一种选择:

import doSomething from "./doSomething";

const FrequentlyRerendersMap = ({ ids }) => {
  const onEvent = useCallback((id) => () => doSomething(id), []);

  return ids.map(id => {
    
    return (
      <ExpensiveComponent key={id} onEvent={ onEvent: onEvent(id) } />
    );
  });
};