Javascript 以正确的方式实施

Javascript 以正确的方式实施,javascript,reactjs,Javascript,Reactjs,我正在努力理解useMemo的用法。由于对象没有改变,我想我可以通过添加useMemo来提高性能。 然而,当我在这里添加它时,我被要求添加findfoorposition。一旦我这样做了,我的linter就会要求我将useCallback添加到findfoorposition函数中。 你能给我一些建议,在这里实现usemo的正确方法是什么吗 const location = useLocation(); const searchParams = parseQs(location.search);

我正在努力理解useMemo的用法。由于对象没有改变,我想我可以通过添加useMemo来提高性能。 然而,当我在这里添加它时,我被要求添加
findfoorposition
。一旦我这样做了,我的linter就会要求我将
useCallback
添加到
findfoorposition
函数中。 你能给我一些建议,在这里实现
usemo
的正确方法是什么吗

const location = useLocation();
const searchParams = parseQs(location.search);
const goto = searchParams?.goto;

const findFloorPosition = (elementId) => {
  for (const floor of blueprint) {
    for (const room of floor.rooms) {
      const foundElement = room.elements.find(
        (element) => element.id === elementId
      );
      if (foundElement) {
        return floor.position;
      }
    }
  }
};

const currentFloorPosition = useMemo(() => findFloorPosition(goto), [goto]);
此处可能不相关,但此处显示的是
blueprint
对象的外观:

const blueprint = [
  {
    id: "4mD59WO",
    name: "AUDITORIUM",
    position: 1,
    rooms: [
      {
        id: "zR8Qgpj",
        name: "Audimax",
        subtitle: null,
        details: null,
        position: 0,
        elements: [
          {
            id: "1jLv04W",
            position: 0,
            type: "daily",
            element: "listing_large",
            properties: {
              meetingId: null,
              capacity: 6
            }
          },
          {
            id: "1jLv12W",
            position: 1,
            type: "daily",
            element: "listing_large",
            properties: {
              meetingId: null,
              capacity: 6
            }
          }
        ]
      }
    ]
  },
  {
    id: "3mDd9WO",
    name: "FOYER",
    position: 0,
    rooms: [
      {
        id: "4R8Qgpj",
        name: "Speakers Table",
        subtitle: null,
        details: null,
        position: 0,
        elements: [
          {
            id: "2jLv04W",
            position: 0,
            type: "daily",
            element: "listing_large",
            properties: {
              meetingId: null,
              capacity: 6
            }
          },
          {
            id: "2jLv12W",
            position: 1,
            type: "daily",
            element: "listing_large",
            properties: {
              meetingId: null,
              capacity: 6
            }
          }
        ]
      }
    ]
  }
];

请注意,仅当依赖项数组值(
goto
的值)不经常更改时,才应记住一个值

出现警告是因为linter(
eslint
)只计算语义,它不知道
findfoorposition
只是一个辅助函数

因此,基本上需要内联helper函数,如:

const currentFloorPosition = useMemo(() => {
  for (const floor of blueprint) {
    for (const room of floor.rooms) {
      const foundElement = room.elements.find(
        (element) => element.id === goto
      );
      if (foundElement) {
        return floor.position;
      }
    }
  }
  return null;
}, [goto]);

// Or
const currentFloorPosition = useMemo(() => {
  const findFloorPosition = (elementId) => {
  for (const floor of blueprint) {
    for (const room of floor.rooms) {
      const foundElement = room.elements.find(
        (element) => element.id === elementId
      );
      if (foundElement) {
        return floor.position;
      }
    }
  }
};
  return findFloorPosition(goto);
}, [goto]);

由于功能组件严重依赖闭包,因此在记忆函数时,使用闭包中正确且更新的值非常重要

eslint
警告您将
findfoorposition
添加到依赖项的原因是为了确保findfoorposition中没有任何内容引用旧值

上面的代码可以实现如下

const findFloorPosition = useCallback((elementId) => {
  for (const floor of blueprint) {
    for (const room of floor.rooms) {
      const foundElement = room.elements.find(
        (element) => element.id === elementId
      );
      if (foundElement) {
        return floor.position;
      }
    }
  }
}, [blueprint]);

const currentFloorPosition = useMemo(() => findFloorPosition(goto), [goto, findFloorPosition]);

你是在问如何用
useMemo
实现这个逻辑,还是在问什么是正确的决策?我认为useMemo在这里是有意义的(它只需要渲染一次,因为对象“蓝图”没有改变)。所以我更想知道如何实现它的逻辑。例如,我是否也必须使用
useCallback
@joycoder?你的措辞令人困惑。通常,如果你试图“实现”某些东西,你是在创造它,而不是在使用它。您的问题似乎是关于如何正确使用
useMemo
,而不是如何实现它。谢谢Shubham。这很有帮助。我将向Dennis的答案发布一个后续问题,因为我想知道使用
useCallback
与按照他的建议将函数引入useMemo相比是否有任何优势。当您不仅想在useMemo中使用函数,还想在代码中的其他地方使用函数时,useCallback会派上用场。很明显,您可以在usemo中编写逻辑和函数,避免将其作为依赖项,以防您只是在usemo中使用该函数,而不打算在将来的任何其他地方使用它。明白了,这就是我的想法。谢谢你的解释。非常有帮助!很高兴能帮上忙:-)谢谢你的回答。Shubham,刚才也用
useCallback
回答了。使用useCallback有什么好处吗?或者我应该根据偏好选择一个。如果我在组件中多次使用findFloorPosition,我认为useCallback是有意义的。
useCallback
可以使用文档中所述的
UseMoom
实现。我的回答基于您的评论“所以我更想知道如何实现它的逻辑”,林特提到的
blueprint
是缺失的,因为依赖关系在这种情况下很好,因为我知道它不会改变?我不知道blueprint从何而来,如果它说它缺失了,那么你应该这样做。似乎它是一个状态或道具,而不是一个全局变量。