03_React 收集表单数据和 组件生命周期

React 收集表单数据和 组件生命周期

    • 一、收集表单数据
      • 1、例子
        • 1.1 需求:定义一个包含表单的组件,输入用户名密码后,点击登录提示输入信息
      • 2、理解:包含表单的组件分类
        • 2.1 受控组件
        • 2.2 非受控组件
    • 二、高阶函数\_函数柯里化
      • 1、复习--对象相关的知识
      • 2、高阶函数
      • 3、函数柯里化
      • 4、不用柯里化的写法
    • 三、组件的生命周期
      • 1、例子--引出生命周期
      • 2、理解
      • 3、生命周期(旧)
        • 3.1 挂载时(初始化)的流程
        • 3.2 更新时的流程
          • 3.2.1 流程线路 2(setState 流程)
          • 3.2.2 流程线路 3 (forceUpdate 流程)
          • 3.2.3 流程线路 1 (父组件 render 流程)
        • 3.3 总结生命周期(旧)
      • 4、对比新旧生命周期
        • 4.1 重要的钩子
        • 4.2 即将废弃的钩子
        • 4.3 getSnapshotBeforeUpdate的使用场景
        • 4.3 总结新的生命周期(常用的 render、ComponentDidMount、componentWillUnmount 是没有更改的)

一、收集表单数据

1、例子

1.1 需求:定义一个包含表单的组件,输入用户名密码后,点击登录提示输入信息
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>收集表单数据</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">// 1、创建组件class Login extends React.Component {render() {return (<form action="xxx" onSubmit={this.submit}>用户名:<inputtype="text"ref={(c) => {this.username = c}}placeholder="用户名"name="username"/><br />密码:<inputtype="password"ref={(c) => {this.password = c}}placeholder="密码"name="password"/><button>登录</button></form>)}submit = (e) => {e.preventDefault()let { password, username } = thisconsole.log(password.value, username.value)}}// 2、渲染组件到页面// ReactDOM.render(组件,容器)ReactDOM.render(<Login />, document.getElementById('test'))</script></body>
</html>

2、理解:包含表单的组件分类

2.1 受控组件

页面中所有的输入类的节点,随着输入将数据维护到状态中,使用的时候直接从状态中取,就是受控组件
受控组件的优势在于 可以减少 ref 的使用

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>受控组件</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">// 1、创建组件class Login extends React.Component {// 初始化状态state = {username: '',password: '',}render() {return (<form action="xxx" onSubmit={this.submit}>用户名:<inputtype="text"onChange={this.saveUsername}placeholder="用户名"name="username"/><br />密码:<inputtype="password"onChange={this.savePassword}placeholder="密码"name="password"/><button>登录</button></form>)}// 保存用户名到状态中saveUsername = (event) => {this.setState({ username: event.target.value })}// 保存密码到状态中savePassword = (event) => {this.setState({ password: event.target.value })}// 表单提交回调submit = (e) => {e.preventDefault()let { password, username } = this.stateconsole.log(password, username)}}// 2、渲染组件到页面// ReactDOM.render(组件,容器)ReactDOM.render(<Login />, document.getElementById('test'))</script></body>
</html>
2.2 非受控组件

页面中所有的输入类的节点,现用现取就是 非受控组件

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>收集表单数据</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">// 1、创建组件class Login extends React.Component {render() {return (<form action="xxx" onSubmit={this.submit}>用户名:<inputtype="text"ref={(c) => {this.username = c}}placeholder="用户名"name="username"/><br />密码:<inputtype="password"ref={(c) => {this.password = c}}placeholder="密码"name="password"/><button>登录</button></form>)}submit = (e) => {e.preventDefault()let { password, username } = thisconsole.log(password.value, username.value)}}// 2、渲染组件到页面// ReactDOM.render(组件,容器)ReactDOM.render(<Login />, document.getElementById('test'))</script></body>
</html>

二、高阶函数_函数柯里化

1、复习–对象相关的知识

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script type="text/javascript">let a = 'name'let obj = {} // {name: 'Tom'}obj[a] = 'Tom'console.log(obj)</script></body>
</html>

2、高阶函数

如果一个函数符合下面 2 个规范中任何一个,那么该函数就是高阶函数
1)若 A 函数,接收的参数是一个函数,那么 A 就可以称为高阶函数
2)若 A 函数,调用的返回值依然是一个函数,那么 A 就可以称之为高阶函数

常见的高阶函数: arr.map()、arr.filter()、Promise、arr.find()、arr.reduce()、setTimout 等等

下面代码中的 saveFormData 函数就是一个高阶函数,符合了条件 2(返回值是一个函数)

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>高阶函数_函数柯里化</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">// 1、创建组件class Login extends React.Component {// 初始化状态state = {username: '',password: '',}render() {return (<form action="xxx" onSubmit={this.submit}>用户名:<inputtype="text"onChange={this.saveFormData('username')}placeholder="用户名"name="username"/><br />密码:<inputtype="password"onChange={this.saveFormData('password')}placeholder="密码"name="password"/><button>登录</button></form>)}// 保存表单数据到状态中saveFormData = (dataType) => {// 把此函数交给 react 处理,react 可以传入一个 eventreturn (event) => {console.log(dataType, event.target.value, this.state)this.setState({ [dataType]: event.target.value })}// this.setState({ type: event.target.value })}// 表单提交回调submit = (e) => {e.preventDefault()let { password, username } = this.stateconsole.log(password, username)}}// 2、渲染组件到页面// ReactDOM.render(组件,容器)ReactDOM.render(<Login />, document.getElementById('test'))</script></body>
</html>

3、函数柯里化

通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
上一段代码中的 saveFormData 函数 就是一个函数柯里化

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>演示柯里化</title></head><body><script type="text/javascript">function sum(a) {return (b) => {return (c) => {return a + b + c}}}console.log(sum(1)(12)(3))</script></body>
</html>

4、不用柯里化的写法

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>不用函数柯里化的实现</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">// 1、创建组件class Login extends React.Component {// 初始化状态state = {username: '',password: '',}render() {return (<form action="xxx" onSubmit={this.submit}>用户名:<inputtype="text"onChange={(event) => {this.saveFormData('username', event)}}placeholder="用户名"name="username"/><br />密码:<inputtype="password"onChange={(event) => {this.saveFormData('password', event)}}placeholder="密码"name="password"/><button>登录</button></form>)}// 保存表单数据到状态中saveFormData = (dataType, event) => {this.setState({ [dataType]: event.target.value })}// 表单提交回调submit = (e) => {e.preventDefault()let { password, username } = this.stateconsole.log(password, username)}}// 2、渲染组件到页面// ReactDOM.render(组件,容器)ReactDOM.render(<Login />, document.getElementById('test'))</script></body>
</html>

三、组件的生命周期

1、例子–引出生命周期

需求:自定义组件实现以下功能
1)让指定的文本做显示/隐藏 的渐变动画
2)从完全可见,到彻底消失,耗时 2s
3)点击 按钮 从界面卸载组件

挂载 mount
卸载 unMount

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>引出生命周期</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">// 1、创建组件// 生命周期回调函数《==》生命周期钩子函数《==》生命周期函数《==》生命周期钩子class Life extends React.Component {// 初始化状态state = {opacity: 1,}// render 调用的时机: 初始化渲染、状态更新之后render() {console.log('render')return (<div><h2 style={{ opacity: this.state.opacity }}>React 学不会,咋可能啊</h2><button onClick={this.deadHandle}>直接噶</button></div>)}// componentDidMount 组件挂载完毕时调用componentDidMount() {console.log('componentDidMount')this.timer = setInterval(() => {let { opacity } = this.stateopacity -= 0.1if (opacity <= 0) {opacity = 1}// console.log(opacity)this.setState({ opacity })}, 200)}// 组件将要卸载的时候调用componentWillUnmount() {// 清除定时器clearInterval(this.timer)}deadHandle = () => {// // 清除定时器// clearInterval(this.timer)// 卸载组件ReactDOM.unmountComponentAtNode(document.getElementById('test'))console.log('按钮点击,将组件直接卸载')}}// 2、渲染组件到页面// ReactDOM.render(组件,容器)ReactDOM.render(<Life />, document.getElementById('test'))</script></body>
</html>

2、理解

1)组件对象从创建到死亡它会经历特定阶段
2)React 组件对象包含一系列钩子函数(生命周期回调函数),在特定的时刻调用
3)我们在定义组件时候,在特定的生命周期回调函数中做特定的工作

3、生命周期(旧)

react v16.8.0
在这里插入图片描述

3.1 挂载时(初始化)的流程

执行顺序:
Count—constructor
Count—componentWillMount
Count—render
Count—componentDidMount

卸载组件按钮点击后执行:
Count—componentWillUnmount

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">class Count extends React.Component {constructor(props) {console.log('Count---constructor')super(props)this.state = {num: 0,}}addHandle = () => {let { num } = this.statethis.setState({ num: num + 1 })}death = () => {ReactDOM.unmountComponentAtNode(document.getElementById('test'))}// 组件将要挂载的钩子componentWillMount() {console.log('Count---componentWillMount')}// 组件挂载完毕的钩子componentDidMount() {console.log('Count---componentDidMount')}// 组件卸载时的钩子componentWillUnmount() {console.log('Count---componentWillUnmount')}render() {console.log('Count---render')let { num } = this.statereturn (<div><h1>当前求和为 {num}</h1><button onClick={this.addHandle}>点我+1</button><button onClick={this.death}>卸载组件</button></div>)}}ReactDOM.render(<Count />, document.getElementById('test'))</script></body>
</html>
3.2 更新时的流程

在这里插入图片描述

3.2.1 流程线路 2(setState 流程)

正常更新:修改状态中的数据 组件能够更新

执行顺序
Count—shouldComponentUpdate
Count—componentWillUpdate
Count—render
Count—componentDidUpdate

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">class Count extends React.Component {constructor(props) {console.log('Count---constructor')super(props)this.state = {num: 0,}}addHandle = () => {let { num } = this.statethis.setState({ num: num + 1 })}death = () => {ReactDOM.unmountComponentAtNode(document.getElementById('test'))}// 组件将要挂载的钩子componentWillMount() {console.log('Count---componentWillMount')}// 组件挂载完毕的钩子componentDidMount() {console.log('Count---componentDidMount')}// 组件卸载时的钩子componentWillUnmount() {console.log('Count---componentWillUnmount')}// 控制组件更新的“阀门”, 需要写一个返回值(类型为 boolean),返回false就不再更新shouldComponentUpdate() {console.log('Count---shouldComponentUpdate')return true}// 组件将要更新的钩子componentWillUpdate() {console.log('Count---componentWillUpdate')}// 组件更新完毕的钩子componentDidUpdate() {console.log('Count---componentDidUpdate')}render() {console.log('Count---render')let { num } = this.statereturn (<div><h1>当前求和为 {num}</h1><button onClick={this.addHandle}>点我+1</button><button onClick={this.death}>卸载组件</button></div>)}}ReactDOM.render(<Count />, document.getElementById('test'))</script></body>
</html>
3.2.2 流程线路 3 (forceUpdate 流程)

强制更新: 不修改状态中的数据但是想要更新页面就会用到。 阀门关闭也不会影响
执行顺序:
Count—componentWillUpdate
Count—render
Count—componentDidUpdate

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">class Count extends React.Component {constructor(props) {console.log('Count---constructor')super(props)this.state = {num: 0,}}addHandle = () => {let { num } = this.statethis.setState({ num: num + 1 })}// 卸载组件按钮的回调death = () => {ReactDOM.unmountComponentAtNode(document.getElementById('test'))}// 强制更新按钮的回调force = () => {this.forceUpdate()}// 组件将要挂载的钩子componentWillMount() {console.log('Count---componentWillMount')}// 组件挂载完毕的钩子componentDidMount() {console.log('Count---componentDidMount')}// 组件卸载时的钩子componentWillUnmount() {console.log('Count---componentWillUnmount')}// 控制组件更新的“阀门”, 需要写一个返回值(类型为 boolean),返回false就不再更新shouldComponentUpdate() {console.log('Count---shouldComponentUpdate')return true}// 组件将要更新的钩子componentWillUpdate() {console.log('Count---componentWillUpdate')}// 组件更新完毕的钩子componentDidUpdate() {console.log('Count---componentDidUpdate')}render() {console.log('Count---render')let { num } = this.statereturn (<div><h1>当前求和为 {num}</h1><button onClick={this.addHandle}>点我+1</button><button onClick={this.death}>卸载组件</button><button onClick={this.force}>不更改任何状态的数据,强制更新一下</button></div>)}}ReactDOM.render(<Count />, document.getElementById('test'))</script></body>
</html>
3.2.3 流程线路 1 (父组件 render 流程)

执行顺序:
Child—render
Child—componentWillReceiveProps {carName: ‘奥迪’}
Child—shouldComponentUpdate
Child—componentWillUpdate
Child—render
Child—componentDidUpdate

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">class Parent extends React.Component {// 初始化状态state = {carName: '奔驰',}changeCar = () => {this.setState({ carName: '奥迪' })}render() {let { carName } = this.statereturn (<div>Parent, 我是父组件<button onClick={this.changeCar}>换车</button><Child carName={carName} /></div>)}}class Child extends React.Component {// 组件将要接收新的prps 的钩子第一次传的不算, 之后的就能够执行,还能够接收到props参数componentWillReceiveProps(props) {console.log('Child---componentWillReceiveProps', props)}// 控制组件更新的“阀门”, 需要写一个返回值(类型为 boolean),返回false就不再更新shouldComponentUpdate() {console.log('Child---shouldComponentUpdate')return true}// 组件将要更新的钩子componentWillUpdate() {console.log('Child---componentWillUpdate')}// 组件更新完毕的钩子componentDidUpdate() {console.log('Child---componentDidUpdate')}render() {console.log('Child---render')return <div>Child, 我是子组件,接收到的车是{this.props.carName}</div>}}ReactDOM.render(<Parent />, document.getElementById('test'))</script></body>
</html>
3.3 总结生命周期(旧)

生命周期的三个阶段
**1、初始化阶段:**由 ReactDom.render() 触发—初次渲染
constructor()
componentWillMount()
render()
componentDidMount() ====》常用,一般再这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
**2、更新阶段:**由组件内部 this.setState() 或父组件重新 render 触发
shouldComponentUpdate()
componentWillUpdate()
render() =======>必须
componentDidUpdate()
**3、卸载组件:**由 ReactDOM.unmountComponentAtNode() 触发
componentWillUnmount() ====》常用,一般再这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

4、对比新旧生命周期

新的生命周期即将不再维护componentWillMount、componentWillUpdate、
新增 getDerivedStateFromProps、getSnapshotBeforeUpdate,但是不是替代之前前面丢弃的钩子,这两个新的钩子基本不用

React v18.3.0
在这里插入图片描述

4.1 重要的钩子

render:初始化渲染或更新渲染调用
ComponentDidMount:开启监听,发送 ajax请求
componentWillUnmount:做一些收尾工作,如:清理定时器

4.2 即将废弃的钩子

omponentWillMount
componentWillUpdate
componentWillUnmount

4.3 getSnapshotBeforeUpdate的使用场景
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>生命周期(新)</title><style>.list {width: 200px;height: 150px;background-color: skyblue;overflow-y: auto;}.news {height: 30px;}
</style></head><body><div id="test"></div><!-- 引入 react 核心库 --><script type="text/javascript" src="../js/v18.3.0/react.development.js"></script><!-- 引入 react-dom,用于支持 react 操作DOM --><scripttype="text/javascript"src="../js/v18.3.0/react-dom.development.js"></script><!-- 引入babel, 用于将 jsx 转为 js --><script type="text/javascript" src="../js/v18.3.0/babel.min.js"></script><!-- 引入 prop-types,用于对组件标签属性进行限制, 存在 PropTypes --><script type="text/javascript" src="../js/v18.3.0/prop-types.js"></script><!-- 此处一定要写babel --><script type="text/babel">class NewsList extends React.Component {state = {newArr:[]}componentDidMount(){this.timer = setInterval(()=>{const {newArr} = this.statelet news = '新闻'+(newArr.length+1)this.setState({newArr: [news, ...newArr]})},1000)}// 在更新之前获取快照getSnapshotBeforeUpdate(){console.log("getSnapshotBeforeUpdate", this.refs.list.scrollHeight)return this.refs.list.scrollHeigh}componentDidUpdate(prePops, preState, height){this.refs.list.scrollTop += this.refs.list.scrollHeight-height}render() {console.log('Count---render')return (<div className="list" ref='list'>{this.state.newArr.map((el,inx)=>{return <div className="news" key={inx}>{el}</div>})}</div>)}}ReactDOM.render(<NewsList />, document.getElementById('test'))</script></body>
</html>
4.3 总结新的生命周期(常用的 render、ComponentDidMount、componentWillUnmount 是没有更改的)

**1、初始化阶段:**由 ReactDom.render() 触发—初次渲染
constructor()
getDerivedStateFromProps()
render()
componentDidMount() ====》常用,一般再这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
**2、更新阶段:**由组件内部 this.setState() 或父组件重新 render 触发
getDerivedStateFromProps
shouldComponentUpdate()
render() =======>必须
getSnapshotBeforeUpdate()
componentDidUpdate()
**3、卸载组件:**由 ReactDOM.unmountComponentAtNode() 触发
componentWillUnmount() ====》常用,一般再这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/408049.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

9 正则表达式:Java爬虫和正则表达式、String中的正则表达式方法(基本语法7)

文章目录 前言一、正则表达式1 [ ] 语法(1)[ABC] 和 [^ABC](2)[A-Z]和[a-zA-Z]小总结2 特殊字符语法(\w 这些)3 数量符4 \ 、()、 |5 锚点 ^ 和 $,\b,\B6 (?i) : 忽略其后面的大小写 ---- 这个Java是可以的,其他语言我不知道(正则表达式虽然大多通用,但也有部分是…

zabbix5.0与7.0版本区别 切换建议

Zabbix5.0和Zabbix7.0的区别 1. 性能和扩展性优化 1.1 高效的数据处理和存储 优化的数据库性能&#xff1a; Zabbix 7.0 在数据库层面进行了多项优化&#xff0c;以减少查询延迟和提高数据处理速度。这包括对数据库结构的改进和索引优化&#xff0c;使得大规模数据的读取和写…

Spark-driver和executor启动过程

一、上下文 《Spark-SparkSubmit详细过程》详细分析了从脚本提交任务后driver是如何调用到自己编写的Spark代码的&#xff0c;而我们的Spark代码在运行前必须准备好分布式资源&#xff0c;接下来我们就分析下资源是如何分配的 二、Spark代码示例 我们以一个简单的WordCount程…

打卡学习Python爬虫第五天|Xpath解析的使用

什么是Xpath&#xff1f;是在XML文档中搜索内容的一门语言&#xff0c;HTML可以看作是xml的一个子集。 目录 1、安装lxml模块 2、导入lxml中的etree子模块 3、Xpath使用方法 3.1.选择节点 3.2.选择属性 3.3.选择文本内容 3.4.使用通配符*过滤节点 3.5.使用中括号[]索引…

Java学习_20_File以及IO流

文章目录 前言一、FileFile中常见的成员方法判断和获取创建和删除获取和遍历 二、IO流IO流体系结构字节流字节输出流&#xff1a;FileOutputStream字节输入流FileInputStrea文件拷贝try……catch异常处理中文乱码现象 字符流字符流读取FileReader字符流输出FileWriter底层原理 …

Linux 命令集合

1. linux 系统版本 1.1 linux系统的分类 linux系统&#xff0c;主要分Debian系和RedHat系&#xff0c;还有其它自由的发布版本。 1、Debian系主要有Debian&#xff0c;Ubuntu&#xff0c;Mint等及其衍生版本&#xff1b; 2、RedHat系主要有RedHat&#xff0c;Fedora&#xf…

Springsecurity 自定义AuthenticationManager

一、认证流程 1、当用户提交了一个他的凭证(用户名、密码) AbstractAuthenticationProcessingFilter 将会创建一个凭证信息&#xff0c;最终&#xff0c;该请求会被UsernamePasswordAuthenticationFilter 拦截将请求中用户名和密码&#xff0c;封装为 Authentication 对象&…

C++ | Leetcode C++题解之第365题水壶问题

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canMeasureWater(int x, int y, int z) {if (x y < z) {return false;}if (x 0 || y 0) {return z 0 || x y z;}return z % gcd(x, y) 0;} };

AI大模型进化之路:机器学习九大算法画图详解

机器学习算法对于了解AI大模型的意义非常重要&#xff0c;它们是构建、训练和应用AI大模型的基础和关键。今天给大家整理了一份机器学习核心算法资料&#xff0c;建议收藏学习。 集成学习是一种机器学习算法&#xff0c;它通过构建多个模型并整合它们的预测结果来提高性能。常…

ST 表算法

ST 表 ST 表&#xff0c;主要思想是空间换时间&#xff0c;用于解决可重复贡献问题和 RMQ 问题。 可重复贡献问题 指某个运算 o p op op&#xff0c;有 x o p x x x\ op\ x\ \ x x op x x 。例如 m a x ( x , x ) x m i n ( x , x ) x g c d ( x , x ) x max(x,x)x\…

【Docker】Docker学习01 | 什么是docker?

本文首发于 ❄️慕雪的寒舍 因为本人没有学习过docker&#xff0c;虽然部署过很多镜像&#xff0c;但是对于docker底层的实现一概不知。趁学习一个新项目的契机&#xff0c;将docker的相关概念了解清楚。 安装docker的教程请查看 Linux主机安装docker。 如果你想和我一起学习do…

TCP的连接建立及报文段首部格式

粘包问题&#xff1a; 原因&#xff1a;TCP流式套接字&#xff1b;数据与数据之间没有边界&#xff1b;导致可能多次的数据粘到一起。 解决办法&#xff1a; 规定一些数据与数据之间的间隔符&#xff0c;如&#xff1a;"\aa\", "\r\n"。指定要发送的数据…

exec函数簇

一、main 函数的参数定义 在C语言中&#xff0c;main 函数是程序执行的入口点。main 函数可以接受参数&#xff0c;这些参数通常用于从命令行接收输入。main 函数的参数定义通常遵循以下形式&#xff1a; int main(int argc, char *argv[]) 或者等价地&#xff1a; int mai…

91. UE5 RPG 实现拖拽装配技能以及解除委托的绑定

在上一篇文章里&#xff0c;实现了通过选中技能&#xff0c;然后点击下方的装备技能插槽实现了技能的装配。为了丰富技能装配功能&#xff0c;在这一篇里&#xff0c;我们实现一下通过拖拽技能&#xff0c;实现拖拽功能&#xff0c;我们需要修改两个用户控件&#xff0c;一个就…

杰发科技AC7840——CAN通信简介(8)_通过波特率和时钟计算SEG_1/SEG_2/SJW/PRESC

通过公式计算 * 波特率和采样点计算公式&#xff1a;* tSeg1 (S_SEG_1 2); tSeg2 (S_SEG_2 1).* BandRate (SCR_CLK / (S_PRESC 1) / ((S_SEG_1 2) (S_SEG_2 1))), SCR_CLK 为CAN 模块源时钟* SamplePoint (tSeg1 / (tSeg1 tSeg2)). {0x0D, 0x04, 0x04, 0x3B},…

文件IO和多路复用IO

目录 前言 一、文件 I/O 1.基本文件 I/O 操作 1.1打开文件 1.2读取文件内容 (read) 1.3写入文件 (write) 1.4关闭文件 (close) 2.文件指针 二、多路复用 I/O 1.常用的多路复用 I/O 模型 1.1select 1.2poll 1.3epoll 2.使用 select、poll 和 epoll 进行简单的 I/O…

软件测试最全面试题,了解一下

一、前言 近期有不少同学&#xff0c;朋友问我什么是软件测试&#xff0c;它是干什么的&#xff0c;我适不适合做、这行发展前景、工资怎么样等等等…在这里我把问题总结一下&#xff0c;整理一篇文章出来。 我也看过很多贴吧、论坛&#xff0c;在入行之前对这块都是迷茫的&a…

数据结构----栈

一丶概念 只能在一端进行插入和删除操作的线性表&#xff08;又称为堆栈&#xff09;&#xff0c;进行插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底 二丶特点 先进后出 FILO first in last out 后进先出 LIFO last in first out 三丶顺序栈 逻辑结构&…

Nginx: 配置项之http模块connection和request的用法以及limit_conn和limit_req模块

connection和request connection 就是一个连接, TCP连接 客户端和服务器想要进行通信的话&#xff0c;有很多种方式比如说, TCP的形式或者是UDP形式的通常很多应用都是建立在这个TCP之上的所以, 客户端和服务器通信&#xff0c;使用了TCP协议的话&#xff0c;必然涉及建立TCP连…

Java JNA调用C函数常见问题及解决方法

目录 1 undefined symbol&#xff1a;xxx2 Java映射C数组乱码3 Java使用String接收不到C函数返回的char*4 Unable to load DLL xxx.dll5 java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序6 无效的ELF头7 Structure array elements must use contiguous memory8 j…