React基础
1.Ref事件处理:
- 通过onXxx属性指定事件处理函数(注意大小写)
- React使用的是自定义(合成)事件,而不是使用的原生DOM事件-----为了更好的兼容性
- 通过event.target得到发生事件的DOM元素对象------为了高效
- 通过event.target得到发生事件的DOM元素对象---------不要过渡的使用ref
2.非受控组件(特点:现取现用)
<!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 } = thisalert(`你输入的用户名是${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>
5.受控组件(特点:相当于vue中的双向数据绑定)
<!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.statealert(`你输入的用户名是${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>
6.高阶函数
什么是高阶函数?
如果一个函数符合规范中的任何一个,那该函数就是高阶函数。
-
若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.statealert(`你输入的用户名是${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>
函数柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后一次统一处理的编码形式。
7.组件的生命周期
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.stateopacity -= 0.1if (opacity <= 0) opacity = 1this.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>
b.生命周期组件挂载流程
<!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() ====> 常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息
新旧生命周期对比
左边是旧的生命周期,右边是新的生命周期
总结:新旧生命周期对比,即将废弃三个钩子并且提出了两个新的钩子。