Front-end/react/6.组件生命周期.md

269 lines
7.6 KiB
Markdown
Raw Permalink Normal View History

2023-10-19 02:19:45 -04:00
只有类组件才有生命周期
1. 创建
```html
class LifeCreate extends React.Component{
constructor(props){
super(props)
console.warn('1.生命周期钩子函数constructor')
}
componentDidMount(){
console.warn('3.生命周期钩子函数componentDidMount')
}
render(){
console.warn('2.生命周期钩子函数render')
return (<div><h3>hello</h3></div>)
}
}
```
2. 更新
New props,setState,forceUpdate
```html
class LifeUpdate extends React.Component{
constructor(props){
super(props)
console.warn('1.生命周期钩子函数constructor')
this.state = {
count:0
}
}
componentDidMount(){
console.log(document.getElementById('root'))
console.warn('3.生命周期钩子函数componentDidMount')
}
handlerClick= ()=>{
// this.setState({
// count:this.state.count+1
// })
this.forceUpdate()
}
render(){
console.warn('2.生命周期钩子函数render')
return (<div><Counter count = {this.state.count}/><button onClick={this.handlerClick}>hello</button></div>)
}
}
class Counter extends React.Component{
componentDidUpdate(prevProps){
console.warn('---------------生命周期钩子函数componentDidUpdate')
if(prevProps.count!=this.props.count){
this.setState({})
}
}
render(){
console.warn('---------------生命周期钩子函数render')
return (<p>点击次数{this.props.count}</p>)
}
}
```
3. 卸载
```html
class LifeEnd extends React.Component{
constructor(props){
super(props)
console.warn('1.生命周期钩子函数constructor')
this.state = {
count:0
}
}
componentDidMount(){
console.log(document.getElementById('root'))
console.warn('3.生命周期钩子函数componentDidMount')
}
handlerClick= ()=>{
this.setState({
count:this.state.count+1
})
// this.forceUpdate()
}
render(){
console.warn('2.生命周期钩子函数render')
return (<div>
{this.state.count>3?("goodby"):<Counter count = {this.state.count}/>}
<button onClick={this.handlerClick}>hello</button></div>)
}
}
class Counter extends React.Component{
componentDidUpdate(prevProps){
console.warn('---------------生命周期钩子函数componentDidUpdate')
if(prevProps.count!==this.props.count){
this.setState({})
}
}
componentDidMount(){
this.timerId = setInterval(()=>{
console.log("定时器在执行")
},500)
}
componentWillUnmount(){
clearInterval(this.timerId)
console.warn("结束")
}
render(){
console.warn('---------------生命周期钩子函数render')
return (<p>点击次数{this.props.count}</p>)
}
}
```
# 组件复用
复用组件的状态逻辑1.state2.操作state的方法.
## render props
将要复用的state和操作state的方法封装到一个组件中
添加一个值为函数的prop,通过函数参数来获取(需要组件内部来实现)
使用该函数的返回值,作为要渲染的UI内容
```html
import img from './img/20200205205324.jpg'
import PropTypes from "prop-types"
class RepeatUse extends React.Component {
render(){
return (
<div>
<h1>render props 复用模式</h1>
<Mouse >{mouse=>{return (<p>X:{mouse.x},Y{mouse.y}</p>)}}</Mouse>
<Mouse >{mouse=>{return <img src={img} alt="" style={{position:'absolute',top:mouse.y-350,left:mouse.x-350}} />}}</Mouse>
</div>
)
}
}
class Mouse extends React.Component {
state = {
x: 0, y: 0
}
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
// 监听鼠标移动
componentDidMount() {
window.addEventListener('mousemove', this.handleMouseMove)
}
componentWillUnmount(){
window.removeEventListener('mousemove', this.handleMouseMove)
}
render(){
return this.props.children(this.state)
}
}
Mouse.propTypes={
children:PropTypes.func.isRequired
}
```
## 高阶组件HOC
是一个函数,接收要包装的组件,返回增强后的组件
1. 创建函数以with开头
2. 指定函数参数,参数大写开头
3. 函数内部创建类组件,提供复用状态逻辑代码
4. 在组件中渲染参数组件,同时通过prop传递给参数组件(high order component)
5. 调用高阶组件,传入要增强的组件,通过返回值拿到增强后的组件并将其渲染到页面.
```html
class RepeatUse extends React.Component {
render(){
return (
<div>
<h1>render props 复用模式</h1>
<MoousePosition ></MoousePosition>
</div>
)
}
}
function withMouse(WrappedComponent){
class Mouse extends React.Component {
state = {
x: 0, y: 0
}
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
// 监听鼠标移动
componentDidMount() {
window.addEventListener('mousemove', this.handleMouseMove)
}
componentWillUnmount(){
window.removeEventListener('mousemove', this.handleMouseMove)
}
render(){
// return this.props.children(this.state)
return <WrappedComponent {...this.state}></WrappedComponent>
}
}
return Mouse
}
const Position = props=>(
<p>
鼠标当前位置(x:{props.x},y:{props.y})
</p>
)
const MoousePosition = withMouse(Position)
```
### 设置displayName便于区分
```html
class RepeatUse extends React.Component {
render(){
return (
<div>
<h1>render props 复用模式</h1>
<MoousePosition ></MoousePosition>
{/* <MoousePosition >{mouse=>{return (<p>X:{mouse.x},Y{mouse.y}</p>)}}</MoousePosition> */}
{/* <MoousePosition >{mouse=>{return <img src={img} alt="" style={{position:'absolute',top:mouse.y-350,left:mouse.x-350}} />}}</MoousePosition> */}
</div>
)
}
}
function getDisplayName(WrappedComponent){
return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}
function withMouse(WrappedComponent){
class Mouse extends React.Component {
state = {
x: 0, y: 0
}
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
// 监听鼠标移动,仅挂载执行一次
componentDidMount() {
window.addEventListener('mousemove', this.handleMouseMove)
}
componentWillUnmount(){
window.removeEventListener('mousemove', this.handleMouseMove)
}
render(){
// return this.props.children(this.state)
return <WrappedComponent {...this.state}></WrappedComponent>
}
}
// 设置展示名称
Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}`
return Mouse
}
const Position = props=>(
<p>
鼠标当前位置(x:{props.x},y:{props.y})
</p>
)
const MoousePosition = withMouse(Position)
```
## 高阶组件传递 props
```html
render(){
// return this.props.children(this.state)
return <WrappedComponent {...this.state}{...this.props}></WrappedComponent>
}
```
## 组件极简模型
(state,props)=>UI