【发布时间】:2021-07-05 04:19:43
【问题描述】:
好的,我想我不妨在这里补充一下,我知道代码看起来不太好,但我认为它可以完成这项工作,所以如果你能解释为什么不只是它,我会很高兴如果它有效,那将不是一个好习惯,但为什么它不起作用。我也很高兴听到您对问题的解决方案!
我很难理解为什么下面的代码块似乎没有按预期工作,我的意思是记住 <First /> 和 <Second /> 功能组件的返回值,而不是在每个 @ 上调用它们的函数987654325@ 渲染。我认为由于<SomeComponent /> 表达式返回一个对象,因此可以简单地记住它并继续使用。似乎不起作用,我不知道为什么。
顺便说一句,如果您能解释一下为什么渲染 <App /> 组件会导致 renders.current 值增加 2,而只调用一次 console.log,我将不胜感激。
非常感谢您的帮助!
import "./styles.css";
import React from "react";
const First = () => {
const renders = React.useRef(0);
renders.current += 1;
console.log('<First /> renders: ', renders.current);
return <h1>First</h1>;
}
const Second = () => {
const renders = React.useRef(0);
renders.current += 1;
console.log('<Second /> renders: ', renders.current);
return <h1>Second</h1>;
}
const App = () => {
const [isSwapped, setIsSwapped] = React.useState(false);
const [, dummyState] = React.useState(false);
const first = React.useMemo(() => <First />, []);
const second = React.useMemo(() => <Second />, []);
const renders = React.useRef(0);
renders.current += 1;
console.log('<App /> renders: ', renders.current);
return (
<div className="App">
<button onClick={() => setIsSwapped((isSwapped) => !isSwapped)}>Swap</button>
<button onClick={() => dummyState((state) => !state)}>Re-render</button>
{isSwapped ? (
<>
{first}
{second}
</>
) : (
<>
{second}
{first}
</>
)}
</div>
);
}
编辑:感谢您的回复,伙计们,这是符合预期的版本:https://codesandbox.io/s/why-doesnt-memoization-of-a-react-functional-component-call-with-usememo-hook-forked-gvnn0?file=/src/App.js
【问题讨论】:
-
当您在组件主体中执行一堆副作用(引用计数、控制台日志记录)时,您会得到奇怪的结果。
useMemo钩子用于记忆值,而不是组件,为此使用memo高阶组件。 -
但是功能组件调用的返回不只是另一个值吗?我知道代码不是惯用的,但我不明白为什么它不起作用。此外,在这种情况下,使用 React.memo() 不会改变行为,所以对我来说,这里发生了什么的问题仍然悬而未决
-
嗯,一切都是一个值。你所有的代码都是非常反模式的(虽然你的布尔切换正确,所以 +1 ),你的问题基本上是“为什么我的代码不起作用?”这是因为你没有真正遵循任何既定的 React 准则。如果你想记住一个 React 组件,memo Higher Order Component 就是答案。关于控制台日志和引用突变的其余问题是无意的副作用,因为您没有在生命周期中运行 that 代码,即 useEffect。
-
好吧,感谢您的回复,我只是想知道为什么这个代码是反模式的,以及在引擎盖下发生了什么并不能使它工作。我并不怀疑它不好,但我的问题是为什么会这样。 “因为它不遵循准则”- 这些准则可能更多是我希望理解的一些推理的结果。
-
而且,正如我之前所说,备忘录 HOC 在这里不起作用
标签: reactjs react-hooks