Javascript 以正确的方式实施
我正在努力理解useMemo的用法。由于对象没有改变,我想我可以通过添加useMemo来提高性能。 然而,当我在这里添加它时,我被要求添加Javascript 以正确的方式实施,javascript,reactjs,Javascript,Reactjs,我正在努力理解useMemo的用法。由于对象没有改变,我想我可以通过添加useMemo来提高性能。 然而,当我在这里添加它时,我被要求添加findfoorposition。一旦我这样做了,我的linter就会要求我将useCallback添加到findfoorposition函数中。 你能给我一些建议,在这里实现usemo的正确方法是什么吗 const location = useLocation(); const searchParams = parseQs(location.search);
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从何而来,如果它说它缺失了,那么你应该这样做。似乎它是一个状态或道具,而不是一个全局变量。