DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>非受控组件title>
head>
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script src="../js/prop-types.js">script>
<script type="text/babel">
//表单中输入类的Dom,如果是现用现取就属于非受控组件。如提交表单,现在获取数据,下面紧接着使用就属于现用现取
class Login extends React.Component {
handleSubmit = (event) => {
event.preventDefault();//阻止表单的提交,即在表单提交的时候不进行默认的页面刷新
const { username, password } = this
alert(`你输入的用户名是${username.value},密码是${password.value}`)
}
render() {
return (
<form action="" id='login' onSubmit={this.handleSubmit}>
用户名:<input ref={c => this.username = c} type="text" name='username' /><br />
密 码:<input ref={c => this.password = c} type='password' name='password' /><br />
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login />, document.getElementById("test"))
script>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>受控组件title>
head>
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script src="../js/prop-types.js">script>
<script type="text/babel">
//受控组件相当于vue里面的想象数据绑定,可以通过改变state里面值的内容而改变数据,也可以通过改变数据从而改变值的内容
//表单中输入类的Dom,如果是现用现取就属于非受控组件。如提交表单,现在获取数据,下面紧接着使用就属于现用现取
class Login extends React.Component {
state = {
username: "",//用户名
password: ""//密码
}
saveUsername = (event) => {
this.setState({ username: event.target.value })
}
savePassword = (event) => {
this.setState({ password: event.target.value })
}
handleSubmit = (event) => {
event.preventDefault();//阻止表单的提交,即在表单提交的时候不进行默认的页面刷新
const {username,password}=this.state
alert(`你输入的用户名是${username},密码是${password}`)
}
render() {
return (
<form action="" id='login' onSubmit={this.handleSubmit}>
用户名:<input onChange={this.saveUsername} type="text" name='username' /><br />
密 码:<input onChange={this.savePassword} type='password' name='password' /><br />
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login />, document.getElementById("test"))
script>
body>
html>
什么是高阶函数?
如果一个函数符合规范中的任何一个,那该函数就是高阶函数。
若A函数,接收的参数是一个函数,那么A就可以成为高阶函数
若A函数,调用返回值依然是一个函数,那么A就可以成为高阶函数
常见的高阶函数:Promise,setTimeout,arr,map()等等。
例子如下所示:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>高阶函数title>
head>
<body>
<div id="test">div>
<script src="../js/react.development.js">script>
<script src="../js/react-dom.development.js">script>
<script src="../js/babel.min.js">script>
<script src="../js/prop-types.js">script>
<script type="text/babel">
class Login extends React.Component {
state = {
username: "",//用户名
password: ""//密码
}
saveFormData = (dataType) => {
//event指的是操作的某个元素可以获取相关内容的所有东西
return (event)=>{
console.log(dataType,event.target.value);
}
}
handleSubmit = (event) => {
event.preventDefault();//阻止表单的提交,即在表单提交的时候不进行默认的页面刷新
const {username,password}=this.state
alert(`你输入的用户名是${username},密码是${password}`)
}
render() {
return (
<form action="" id='login' onSubmit={this.handleSubmit}>
用户名:<input onChange={this.saveFormData('username')} type="text" name='username' /><br />
密 码:<input onChange={this.saveFormData('password')} type='password' name='password' /><br />
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login />, document.getElementById("test"))
script>
body>
html>
函数柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后一次统一处理的编码形式。
a.初始生命周期
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>初始生命周期title>
head>
<body>
<div id="test">div>
<script src="../../js/react.development.js">script>
<script src="../../js/react-dom.development.js">script>
<script src="../../js/prop-types.js">script>
<script src="../../js/babel.min.js">script>
<script type="text/babel">
//生命周期回调函数<=>生命周期钩子函数<=>生命周期函数<=>生命周期钩子
class Life extends React.Component {
state = {
opacity: 1
}
death = () => {
// clearInterval(this.timer)
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
//组件挂载完毕之后使用
componentDidMount() {
this.timer = setInterval(() => {
let { opacity } = this.state
opacity -= 0.1
if (opacity <= 0) opacity = 1
this.setState({ opacity })
}, 200)
}
//组件将要卸载
componentWillUnmount() {
clearInterval(this.timer)
}
//render调用时候:1.初始化渲染,2.状态更新之后
render() {
return (
<div>
<h2 style={{ opacity: this.state.opacity }}>React的生命周期</h2>
<button onClick={this.death}>React</button>
</div>
)
}
}
ReactDOM.render(<Life />, document.getElementById('test'))
script>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期钩子title>
head>
<body>
<div id="test">div>
<script src="../../js/react.development.js">script>
<script src="../../js/react-dom.development.js">script>
<script src="../../js/prop-types.js">script>
<script src="../../js/babel.min.js">script>
<script type="text/babel">
//创建组件
class Count extends React.Component {
//构造器
constructor(props) {
console.log('count-constructor');
super(props)
//初始化状态
this.state = { count: 0 }
}
add = () => {
//获取原状态
const { count } = this.state;
//更新状态
this.setState({ count: count + 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');
const { count } = this.state;
return (
<div>
<h2>当前求和为{count}</h2>
<button onClick={this.add}>点我加一</button>
<button onClick={this.death}>点我卸载组件</button>
</div>
)
}
}
//渲染组件
ReactDOM.render(<Count />, document.getElementById("test"))
script>
body>
html>
c.组件更新
方式一:setState更新流程
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期钩子title>
head>
<body>
<div id="test">div>
<script src="../../js/react.development.js">script>
<script src="../../js/react-dom.development.js">script>
<script src="../../js/prop-types.js">script>
<script src="../../js/babel.min.js">script>
<script type="text/babel">
//创建组件
class Count extends React.Component {
//构造器
constructor(props) {
console.log('count-constructor');
super(props)
//初始化状态
this.state = { count: 0 }
}
add = () => {
//获取原状态
const { count } = this.state;
//更新状态
this.setState({ count: count + 1 })
}
//卸载组件按钮的回调
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
//组件将要挂载的钩子
componentWillMount() {
console.log('count-componentWillMount');
}
//组件挂载完毕的钩子
componentDidMount() {
console.log('count-componentDidMount');
}
//组件将要卸载的钩子
componentWillUnmount() {
console.log('count-componentWillUnmount');
}
//控制组件更新的"阀门"
shouldComponentUpdate() {
//这个钩子的返回值为true或false,如果不写返回值虽然会输出'count-shouldComponentUptade'但是后面会报错,下面的操作无法执行。
//如果返回值为true,阀门开启可以进行下一步的操作,进行数据的更新
console.log('count-shouldComponentUptade');
return true
}
//组件将要更新的钩子
componentWillUpdate(){
console.log('count-componentWillUpdate');
}
//组件更新完毕的钩子
componentDidUpdate(){
console.log('count-componentDidUpdate');
}
render() {
console.log('count-render');
const { count } = this.state;
return (
<div>
<h2>当前求和为{count}</h2>
<button onClick={this.add}>点我加一</button>
<button onClick={this.death}>点我卸载组件</button>
</div>
)
}
}
//渲染组件
ReactDOM.render(<Count />, document.getElementById("test"))
script>
body>
html>
方式二.forceUpdate():强制更新
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期钩子title>
head>
<body>
<div id="test">div>
<script src="../../js/react.development.js">script>
<script src="../../js/react-dom.development.js">script>
<script src="../../js/prop-types.js">script>
<script src="../../js/babel.min.js">script>
<script type="text/babel">
//创建组件
class Count extends React.Component {
//构造器
constructor(props) {
console.log('count-constructor');
super(props)
//初始化状态
this.state = { count: 0 }
}
add = () => {
//获取原状态
const { count } = this.state;
//更新状态
this.setState({ count: count + 1 })
}
//卸载组件按钮的回调
death = () => {
ReactDOM.unmountComponentAtNode(document.getElementById('test'))
}
//强制更新组件按钮的回调------与正常操作相比:忽略阀门的控制,直接进行后续的操作
force = () => {
console.log('强制更新', this);
this.forceUpdate()
}
//组件将要挂载的钩子
componentWillMount() {
console.log('count-componentWillMount');
}
//组件挂载完毕的钩子
componentDidMount() {
console.log('count-componentDidMount');
}
//组件将要卸载的钩子
componentWillUnmount() {
console.log('count-componentWillUnmount');
}
//控制组件更新的"阀门"
shouldComponentUpdate() {
//这个钩子的返回值为true或false,如果不写返回值虽然会输出'count-shouldComponentUptade'但是后面会报错,下面的操作无法执行。
//如果返回值为true,阀门开启可以进行下一步的操作,进行数据的更新
console.log('count-shouldComponentUptade');
return true
}
//组件将要更新的钩子
componentWillUpdate() {
console.log('count-componentWillUpdate');
}
//组件更新完毕的钩子
componentDidUpdate() {
console.log('count-componentDidUpdate');
}
render() {
console.log('count-render');
const { count } = this.state;
return (
<div>
<h2>当前求和为{count}</h2>
<button onClick={this.add}>点我加一</button>
<button onClick={this.death}>点我卸载组件</button>
<button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
</div>
)
}
}
//渲染组件
ReactDOM.render(<Count />, document.getElementById("test"))
script>
body>
html>
方式三:父组件render流向
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期父组件render流向title>
head>
<body>
<div id="test">div>
<script src="../../js/react.development.js">script>
<script src="../../js/react-dom.development.js">script>
<script src="../../js/prop-types.js">script>
<script src="../../js/babel.min.js">script>
<script type="text/babel">
class A extends React.Component {
//初始化状态
state = { carName: '奔驰' }
changeCar = () => {
this.setState({ carName: "奥拓" })
}
render() {
return (
<div>
<div>A</div>
<button onClick={this.changeCar}>换车</button>
<B carName={this.state.carName} />
</div>
)
}
}
class B extends React.Component {
//组件将要接收新的props的钩子
//该狗子第一次接收到参数不算,从第二次接收才开始执行此钩子
componentWillReceiveProps(props) {
console.log('B-----componentWillReactiveProps', props);
}
//控制组件更新的"阀门"
shouldComponentUpdate() {
//这个钩子的返回值为true或false,如果不写返回值虽然会输出'count-shouldComponentUptade'但是后面会报错,下面的操作无法执行。
//如果返回值为true,阀门开启可以进行下一步的操作,进行数据的更新
console.log('B-shouldComponentUptade');
return true
}
//组件将要更新的钩子
componentWillUpdate() {
console.log('B-componentWillUpdate');
}
//组件更新完毕的钩子
componentDidUpdate() {
console.log('B-componentDidUpdate');
}
render() {
return (
<div>B,接受到的车是:{this.props.carName}</div>
)
}
}
ReactDOM.render(<A />, document.getElementById("test"))
script>
body>
html>
总结:
1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
1. constructor()
2. componentWillMount()
3. render()
4. componentDidMount() ====> 常用,一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息
2. 更新阶段: 由组件内部this.setState()或父组件render触发
1. shouldComponentUpdate()
2. componentWillUpdate()
3. render() ----------是必须使用的一个
4. componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
1. componentWillUnmount() ====> 常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
新旧生命周期对比
左边是旧的生命周期,右边是新的生命周期
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vdnUXH5Y-1681607678919)(C:\Users\86157\AppData\Roaming\Typora\typora-user-images\image-20230414163146469.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KAIAEsz3-1681607678919)(C:\Users\86157\AppData\Roaming\Typora\typora-user-images\image-20230414163536767.png)]
总结:新旧生命周期对比,即将废弃三个钩子并且提出了两个新的钩子。
()或父组件render触发
1. shouldComponentUpdate()
2. componentWillUpdate()
3. render() ----------是必须使用的一个
4. componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
1. componentWillUnmount() ====> 常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
新旧生命周期对比