React 函数组件生命周期
作者:互联网
React 函数组件生命周期
生命周期方法是在组件的不同阶段执行的自定义功能。当组件被创建并插入 DOM 时,有一些方法可用( 安装 )、组件更新时以及组件从 DOM 中卸载或移除时。
以下是类组件的生命周期方法:
我们想知道如何在组件函数中实现这些方法。
构造函数()
在基于类的组件中,我们经常看到使用构造函数来初始化状态的代码,如下所示:
类应用扩展组件{
构造函数(道具){
超级(道具);
这个.state = {
计数器:0
};
} 渲染 = () => {
返回 (
<button
onClick={() =>
this.setState(prevState => {
返回 { 计数器:prevState.counter + 1 };
})
}
>
增量:{this.state.counter}
</button>
);
};
}
但完全相同的事情可以这样完成:
类应用扩展组件{
状态={计数器:0}; 渲染 = () => {
返回 (
<button
onClick={() =>
this.setState(prevState => {
返回 { 计数器:prevState.counter + 1 };
})
}
>
增量:{this.state.counter}
</button>
);
};
}
如您所见,您可以直接在类下声明初始状态。
当您查看 Hooks 的常见问题解答时 reactjs.org ,它有一个部分专门回答,“生命周期方法如何对应Hooks?”本节的第一个要点说:
_构造函数_
: 函数组件不 ** 需要** (重点:我的)一个构造函数。您可以在_使用状态_
称呼。如果计算初始状态很昂贵,您可以将函数传递给_使用状态_
.
当我想到构造函数时,我会想到这些特征。
- 运行的代码 在此组件的生命周期中的任何其他内容之前 .
- 运行一次的代码, 而且只有一次 , 用于该组件的整个生命周期。
因此,尽管 Hooks 团队做出了大胆的断言,但事实是 是 当我 做 需要一个构造函数(或一些等价物)。
自定义挂钩救援
我们可以 进口 将“类构造器”功能添加到任何需要的功能组件中。代码如下所示:
const useConstructor(callBack = () => {}) => {
常量 [hasBeenCalled, setHasBeenCalled] = useState(false);
if (hasBeenCalled) 返回;
打回来();
setHasBeenCalled(true);
} 常量应用 = () => {
使用构造器(()=> {
控制台日志(
“这只会发生一次。
它发生在初始渲染之前。”
);
});
const [计数器,setCounter] = useState(0); 返回 (
<>
<div>计数器:{计数器}</div>
<div style={{ marginTop: 20 }}>
<button onClick={() =>设置计数器(计数器 + 1)}></button>
增量
</button>
</div>
</>
);
};
如果您将该逻辑放在函数声明的最顶部,则它实际上是一个“构造函数”,无论出于何种意图和目的。
GetDerivedStateFromProps()
虽然你可能 不需要它 , 在极少数情况下您会这样做(例如实施 <Transition>
组件),您可以在渲染期间更新状态。 React 将在退出第一次渲染后立即以更新的状态重新运行组件,因此它不会很昂贵。
在这里,我们存储之前的值 排 prop 在状态变量中,以便我们可以比较:
函数滚动视图({row}){
const [isScrollingDown, setIsScrollingDown] = useState(false);
常量 [prevRow, setPrevRow] = useState(null);如果(行!== prevRow){
// 自上次渲染后行已更改。更新 isScrollingDown。
setIsScrollingDown(prevRow !== null && row > prevRow);
setPrevRow(行);
} return `向下滚动:${isScrollingDown}`;
}
渲染期间的更新正是 getDerivedStateFromProps 在概念上一直是这样的。
使成为()
在基于类的组件中,我们有一个舒适(恕我直言) 使成为()
功能。如果某个特定的逻辑应该 不是 运行 每一个 重新渲染,这个过程非常简单:只是不要把那个逻辑 在 这 使成为()
功能。
但是功能组件没有提供开箱即用的等效项。这是函数组件体本身。那里 没有 使成为()
功能。只有一个 返回
.这 返回
(以及函数体中的所有其余代码)被调用 每次调用此函数 .
常量应用 = () => {
const [计数器,setCounter] = useState(0); _console.log("每次渲染都会发生这种情况。");_ 返回 (
<>
<div>计数器:{计数器}</div>
<div style={{ marginTop: 20 }}>
<button onClick={() =>setCounter(counter + 1)}>增量</button>
</div>
</>
);
};
ComponentWillMount()、ComponentDidMount()、ComponentDidUpdate()、ComponentWillUnmount()
这 使用效果 hook 可以表达这些的所有组合。了解我们如何使用 组件WillMount 对于功能组件,首先我们需要看看组件如何使用 useEffect 管理挂载。
常量应用 = () => {
使用效果(()=> {
控制台日志(
“这只发生一次。它发生在初始渲染之后。”
);
}, []);
};
如果在 useEffect 函数中添加返回函数,它会在组件从 DOM 卸载时触发。这看起来像:
常量应用 = () => {
使用效果(()=> {
返回 () => {
控制台日志(
“这只会发生一次。
这里的任何东西都会在组件 UNMOUNT 上触发。”
);
}
}, []);
};
结合两种解决方案:
这意味着您可以在同一个 useEffect 函数调用中使用 componentDidMount 和 componentWillMount。显着减少管理这两个生命周期事件所需的代码量。这意味着您可以轻松地在功能组件中使用 componentDidMount 和 componentWillMount。
像这样:
常量应用 = () => {
使用效果(()=> {
控制台日志(
“这只会发生一次。
这里的任何东西都会在组件 MOUNT 上触发。”
);
返回 () => {
控制台日志(
“这只会发生一次。
这里的任何东西都会在组件 UNMOUNT 上触发。”
);
}
}, []);
};
componentWillMount 和 componentWillUnmount,非常相似!
应该组件更新()
您可以使用 反应备忘录 浅比较它的道具:
const Button = React.memo((props) => {
// 你的组件
});
它不是 Hook,因为它不像 Hook 那样组成。 反应备忘录 等价于 PureComponent,但它只比较 props。 (您还可以添加第二个参数来指定一个自定义比较函数,该函数采用新旧道具。如果它返回 true,则跳过更新。)
反应备忘录 不比较状态,因为没有要比较的单个状态对象。但是你也可以让孩子变得纯洁,甚至优化个别孩子 使用备忘录 .
getSnapshotBeforeUpdate(),
componentDidCatch() 和 getDerivedStateFromError()
这些方法还没有 Hook 等价物,但很快就会添加。
结论
React 组件生命周期一开始可能会令人生畏,并且可能会有些混乱,但希望这能让您更好地理解函数组件中的这个概念。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
本文链接:https://www.qanswer.top/33146/35001308
标签:生命周期,函数,渲染,React,计数器,组件,构造函数 来源: https://www.cnblogs.com/amboke/p/16688001.html