关于React入门基础从哪学起?
文章目录
- 前言
- 一、React简介
- 1. React是什么
- 2. react 与 vue 最大的区别就是:
- 3. React特点
- 4. React介绍描述
- 5. React高效的原因
- 6.React强大之处
- 二、React基础格式
- 1.什么是虚拟dom?
- 2.为什么要创建虚拟dom?
- 三、React也分为俩种创建方式
- 1. 使用js的方式来创建
- 2.使用jsx方式创建
- 四、jsx的语法规则
- 五、react定义组件
- 1.函数式组件
- 2.类式组件
- 3.函数式组件和类式组件的区别
- 六、 组件实例的三大属性
- 1.state
- 2.props
- 3、ref
- 七 、事件处理
- 八、react收集表单
- 1.非受控组件
- 2.受控组件
- 九、高阶函数
- 1.高阶函数
- 2.函数柯里化
- 十、 组件的生命周期
- 1.什么是组件的生命周期:
- 2.钩子函数的作用:
- 3.生命周期的意义:
- 4.生命周期使用场景
- 5.react 生命周期(旧)
- 6.React 生命周期(新)
- 7. 重要的勾子
- 8. 即将废弃的勾子
- 总结
前言
英文官网
中文官网
自己整理的react文档,结合官网和所学知识的一个总结希望对各位有用。话不多说看下文:
一、React简介
1. React是什么
2. react 与 vue 最大的区别就是:
在表层上,模板的语法不同,React是通过JSX渲染模板。. 而Vue是通过一种拓展的HTML语法进行渲染,但其实这只是表面现象,毕竟React并不必须依赖JSX。. 在深层上,模板的原理不同,这才是他们的本质区别:React是在组件JS代码中,通过原生JS实现模板中的常见语法,比如插值,条件,循环等,都是通过JS语法实现的,更加纯粹更加原生。. 而Vue是在和组件JS代码分离的单独的模板中,通过指令来实现的,比如条件语句就需要 v-if 来实现对这一点,这样的做法显得有些独特,会把HTML弄得很乱。
3. React特点
4. React介绍描述
1.用于动态构建用户界面的 JavaScript 库(只关注于视图)2.由Facebook开源
5. React高效的原因
1.使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM。2.DOM Diffing算法, 最小化页面重绘。关于虚拟DOM:1.本质上是object类型的对象(一般对象)2.虚拟DOM比较轻,真实DOM比较重。因为虚拟DOM
6.React强大之处
速度快
它并不直接对DOM进行操作,引入了一个叫做虚拟DOM的概念,安插在javascript逻辑和实际的DOM之间,性能好
很好的跨浏览器兼容
虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。
所有都是component:
组件化的代码更加模块化,重用代码更容易,可维护性高。
单向数据流
Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。
兼容性好
比如使用RequireJS来加载和打包,而Browserify和Webpack适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏
二、React基础格式
<!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>Document</title>
</head><body><div id="test"></div><!-- 引入 react 核心库 --><script src="./js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="./js/react-dom.development.js"></script><!-- 引入 babel1.es6 ==> es52.jsx ==>js --><script src="./js/babel.min.js"></script><script type="text/babel">// 1.创建虚拟 domconst VDOM = <h1>hello word</h1>// 2.渲染到页面中的指定dom// ReactDOM.render(虚拟dom,真实dom)ReactDOM.render(VDOM,document.getElementById('test'))</script>
</body></html>
讲解: 首先我们需要完成基础引入react。然后先创建一个虚拟dom再把虚拟dom在指定元素里渲染成真实dom
1.什么是虚拟dom?
什么是虚拟 DOM? 在 React 中,render 执行的结果得到的并不是真正的 DOM 节点,结果仅仅是轻量级的 JavaScript 对象,我们称之为 virtual DOM。 虚拟 DOM 是 React 的一大亮点,具有 batching (批处理) 和高效的 Diff 算法。
2.为什么要创建虚拟dom?
我们知道,虚拟DOM的概念是由Facebook的React团队最早提出来的,也是React框架的核心概念之一。 它的作用是以js的形式在内存中描述真实的DOM结构,这样当页面内容需要发生变动时,React可以通过对前后虚拟DOM的比对,计算出如何以最小的代价操作真实DOM。
三、React也分为俩种创建方式
1. 使用js的方式来创建
声明 不建议使用 。 代码多
<!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>Document</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 react 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="../js/react-dom.development.js"></script><script type="text/javascript">// 1.创建虚拟 dom// const VDOM = React.createElement(标签名,标签属性,标签内容)const VDOM = React.createElement('h1', { id: "title" }, React.createElement('span',{},"hello react"))// 2.渲染到页面中的指定dom// ReactDOM.render(虚拟dom,真实dom)ReactDOM.render(VDOM, document.getElementById('test'));</script>
</body></html>
2.使用jsx方式创建
声明 建议使用 它会自动转换成js格式 代码简洁(它没有this指向 需要自己绑定this或者使用箭头函数)
<!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>Document</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 react 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="../js/react-dom.development.js"></script><!-- 引入 babel1.es6 ==> es52.jsx ==>js --><script src="../js/babel.min.js"></script><script type="text/babel">// 1.创建虚拟 dom// const VDOM = React.createElement(标签名,标签属性,标签内容)const VDOM = (<h1>hello<span>react-dom</span></h1>)// 2.渲染到页面中的指定dom// ReactDOM.render(虚拟dom,真实dom)ReactDOM.render(VDOM, document.getElementById('test'));</script>
</body></html>
四、jsx的语法规则
<!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>Document</title><style>.title{color: aliceblue;}</style>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 react 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="../js/react-dom.development.js"></script><!-- 引入 babel1.es6 ==> es52.jsx ==>js --><script src="../js/babel.min.js"></script><script type="text/babel">let myData = 'Student';let idData = 'zhongwu';// 1.创建虚拟 dom// const VDOM = React.createElement(标签名,标签属性,标签内容)const VDOM = (<div><h1 className="title" id={idData}>hello, <span>{ myData }</span><input type="text"></input><Good /></h1></div>)// 2.渲染到页面中的指定dom// ReactDOM.render(虚拟dom,真实dom)ReactDOM.render(VDOM,document.getElementById('test'));</script>
</body></html>
注意:
jsx的语法规则:
1.定义虚拟dom时,不要用引号;
2.标签中混入js表达式时,要用{}
3.样式的类名指定不要用class要用className;
4.内联样式,要用style={{key:value}}的形式去写
5.只能有一个根元素
6所有标签都必须要闭合
7. 标签的首字母:
1.若是小写字母开头,则将改标签转化为html同名的元素,渲染到页面
若html没有同名的元素,则报错
2.若大写字母开头,react就会去渲染对应的组件,若组件没有定义,则报错;/
五、react定义组件
**声明:**组件化是React的核心思想,也是我们后续课程的重点,前面我们封装的App本身就是一个组件: 组件化提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。 任何的应用都会被抽象成一颗组件树。 有了组件化的思想,我们在之后的开发中就要充分的利用它。 尽可能的将页面拆分成一个个小的、可复用的组件。 这样让我们的代码更加方便组织和管理,并且扩展性也更强。 React的组件相对于Vue更加的灵活和多样,按照不同的方式可以分成很多类组件: 这些概念有很多重叠,但是他们最主要是关注数据逻辑和UI展示的分离: 当然还有很多组件的其他概念:比如异步组件、高阶组件等,我们后续再学习。
1.函数式组件
<!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>Document</title><style>.title {color: aliceblue;}</style>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 react 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="../js/react-dom.development.js"></script><!-- 引入 babel1.es6 ==> es52.jsx ==>js --><script src="../js/babel.min.js"></script><script type="text/babel">// 1.创建函数式组件function MyComponent() {console.log(this)//undefined ,因为babel编译,开启了严格模式// 一定需要有返回值return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>}// 2.渲染到页面中的指定dom// ReactDOM.render(虚拟dom,真实dom)ReactDOM.render(<MyComponent />, document.getElementById('test'));/*执行ReactDOM.render()方法之后,发生了什么?1.React解析了组件标签,找到了对应的组件2.发现这个组件是一个函数定义的 随后调用改函数,生成了一个虚拟dom3.最后将虚拟dom转化为真实dom,呈现在页面中*/</script>
</body></html>
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>Document</title><style></style>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 react 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="../js/react-dom.development.js"></script><!-- 引入 babel1.es6 ==> es52.jsx ==>js --><script src="../js/babel.min.js"></script><script type="text/babel">// 1.创建一个 类式组件class MyComponent extends React.Component{//render方法是放在原型上// render中的this是谁? ---实例对象render(){console.log('render中的this',this)return <h2>我是用类定义的组件(适用于【复杂组件】的定义)</h2>}}ReactDOM.render(<MyComponent />, document.getElementById('test'));/*执行ReactDOM.render()方法之后,发生了什么?1.React解析了组件标签,找到了对应的组件2.发现这个组件是一个类定义的 随后new出来一个实例对象并通过该实例对象调用原型上的render方法3.最将render() 返回的内容生成一个虚拟dom4.最后将虚拟dom转化为真实dom,呈现在页面中*/let c = new MyComponent();console.log(c)</script>
</body></html>
3.函数式组件和类式组件的区别
1、函数组件是一个纯函数,它接收一个props对象返回一个react元素;而类组件需要去继承React.Component并且创建render函数返回react元素。
2、函数组件没有生命周期和状态state,而类组件有。
3、 官方建议使用函数式组件
六、 组件实例的三大属性
1.state
声明:
状态( state )即数据,是组件内部的私有数据,只能在组件内部使用
state的值是对象,表示一个组件中可以有多个数据
通过 this.state 来获取状态
通过setState修改state数据(注意:state的数据是 只读 的不能修改。想要修改的话用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>Document</title><style></style>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 react 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持忍让传统操作dom --><script src="../js/react-dom.development.js"></script><!-- 引入 babel1.es6 ==> es52.jsx ==>js --><script src="../js/babel.min.js"></script><script type="text/babel">// 1.创建一个 类式组件class Weather extends React.Component {state = { isTian: true, wind: '微风' };render() {let { isTian, wind } = this.state;return <h2 onClick={this.changewWeather}>今天天气很爽 {isTian ? "不冷" : "不热"},{wind}</h2> //istian}changewWeather = () => {let { isTian } = this.state;this.setState({ isTian: !isTian })//这里的修改,是覆盖还是合并?}}ReactDOM.render(<Weather />, document.getElementById('test'));</script>
</body></html>
2.props
**声明:**传数据
<!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>Document</title>
</head>
<style>.title {color: aqua;}
</style><body><div id="test"></div><div id="test1"></div><div id="test2"></div><!-- 引入React核心库 --><script src="../js/react.development.js"></script><!-- 操作dom --><script src="../js/react-dom.development.js"></script><!-- 引入babel ES6==>ES5 JSX==>JS --><script src="../js/babel.min.js"></script><script type="text/babel">class Weather extends React.Component {constructor(props) {//是否接受,取决于是否使用外部数据super(props)//只能上面接受了props,super()就去传递,否则后续的使用,可能就会出现问题}static propTypes = {name: PropTypes.string.isRequired,//限制name为字符串类型,必填// age: PropTypes.number,sex: PropTypes.string,speak: PropTypes.func}static defaultProps = {sex: '男',}render() {let { name, age, sex } = this.propsreturn (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age + 1}</li></ul>)}}/*问题:1.数据类型是否有对应的限制?2.数据的数量 批量传输可以使用展开运算符*/ReactDOM.render(<Weather name="tom" age={26} sex="女" />, document.getElementById('test'))</script>
</body></html>
3、ref
**声明:**在典型的 React 数据流中,props 是父组件与子组件交互的唯一方式。要修改一个子组件,你需要使用新的 props 来重新渲染它。但是,在某些情况下,你需要在典型数据流之外强制修改子组件。被修改的子组件可能是一个 React 组件的实例,也可能是一个 DOM 元素。对于这两种情况,React 提供了使用ref来解决它。
作者:智慧女孩要秃头
链接:https://juejin.cn/post/7047113456993959972
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">class Person extends React.Component {showData = () => {//转款专用:每一个ref都是唯一的,存在this.refs中let { ipt } = this.refs;alert(ipt.value)}getData=()=>{let { ipt1 } = this.refs;alert(ipt1.value)}render() {return (<div><input ref='ipt' type="text" placeholder="请输入数量" /><button onClick={this.showData}>点我提示左侧的数据</button><input onClick={this.getData} ref='ipt1' type="text" placeholder="请输入数量" /></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
七 、事件处理
声明: 1.通过onXxx属性指定事件处理函数(注意大小写)
1)React使用的是自定义(合成)事件, 而不是使用的原生DOM事件 —为了更好的兼容性
2)React中的事件是通过事件委托方式处理的(委托给组件最外层的元素) —为了更加高效
2.通过event.target得到发生事件的DOM元素对象 — 勿过度使用 refs
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><ul><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">class Person extends React.Component {myRef = React.createRef(); //容量为1,只能存一个,多余会覆盖前者myRef1 = React.createRef();showData = (event) => {alert(this.myRef.current.value)console.log(event.target)}showData1 = () => {alert(this.myRef1.current.value)}// 回调函数// 1.自己写的函数// 2.不是自己调用的// 3.这个函数最后执行了render() {return (<div>{/* 这里是jsx注释 */}<input ref={this.myRef} type="text" placeholder="请输入数量" /><button onClick={this.showData}>点我提示左侧的数据</button><input onBlur={this.showData1} ref={this.myRef1} type="text" placeholder="请输入数量" /></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
八、react收集表单
1.非受控组件
**声明:**需要时才手动读取表单输入框中的数据
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">class Person extends React.Component {handler=(event)=>{event.preventDefault();//阻止默认事件 --- 阻止表单跳转let {username,password} = this;alert(`你输入的名字${username.value},密码是${password.value}`)}render() {return (<div><form action="https://www.baidu.com" onSubmit={this.handler}>用户名:<input type="text" name='username' ref={ c =>this.username=c} />密码:<input type="text" name="password" ref={ c =>this.password=c } /><button type="submit">登录</button></form></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">//受控组件class Person extends React.Component {//初始化状态state = {username: '',//用户名password: ''//密码}//保存用户名到状态中saveUsername = (event) => {this.setState({ username: event.target.value })}//保存密码到状态中savePassword = (event) => {this.setState({ password: event.target.value })}//表单提交回调handler = (event) => {event.preventDefault();//阻止默认事件 --- 阻止表单跳转let { username, password } = this.state;alert(`你输入的名字${username},密码是${password}`)}render() {return (<div><form action="https://www.baidu.com" onSubmit={this.handler}>用户名:<input type="text" name='username' onChange={this.saveUsername} />密码:<input type="text" name="password" onChange={this.savePassword} /><button type="submit">登录</button></form></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
九、高阶函数
1.高阶函数
声明:
高阶函数:如果一个函数符合下面2个规范中的任何一个,那么它就是属于一个高阶函数
1.若A函数,接受的参数是一个函数,那么A就可以称为高阶函数
2.若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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">/*
regionfunction sum(a){return (b)=>{return (c)=>{return a+b+c;}}}*///受控组件class Person extends React.Component {//初始化状态state = {username: '',//用户名password: ''//密码}//保存用户名到状态中saveUsername = (event) => {this.setState({ username: event.target.value })}//保存密码到状态中savePassword = (event) => {this.setState({ password: event.target.value })}//保存表单数据到状态中saveFormData = (dataType) => {//这里传来的是标识 标识当前标签return (event)=>{ //这里的回调谁执行?? input标签的 onchange事件// console.log(event.target.value,'@@@')this.setState({[dataType]: event.target.value})// console.log(dataType) // username password }}//表单提交回调handler = (event) => {event.preventDefault();//阻止默认事件 --- 阻止表单跳转let { username, password } = this.state;alert(`你输入的名字${username},密码是${password}`)}render() {return (<div><form action="https://www.baidu.com" onSubmit={this.handler}>用户名:<input type="text" name='username' onChange={this.saveFormData('username')} />密码:<input type="text" name="password" onChange={this.saveFormData('password')} /><button type="submit">登录</button></form></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
2.函数柯里化
声明:
柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">//受控组件class Person extends React.Component {//初始化状态state = {username: '',//用户名password: ''//密码}//保存用户名到状态中saveUsername = (event) => {this.setState({ username: event.target.value })}//保存密码到状态中savePassword = (event) => {this.setState({ password: event.target.value })}//保存表单数据到状态中saveFormData = (dataType, event) => {//这里传来的是标识 标识当前标签this.setState({[dataType]: event.target.value})}//表单提交回调handler = (event) => {event.preventDefault();//阻止默认事件 --- 阻止表单跳转let { username, password } = this.state;alert(`你输入的名字${username},密码是${password}`)}render() {return (<div><form action="https://www.baidu.com" onSubmit={this.handler}>用户名:<input type="text" name='username' onChange={event => this.saveFormData('username', event)} />密码:<input type="text" name="password" onChange={event => this.saveFormData('password', event)} /><button type="submit">登录</button></form></div>)}}ReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
十、 组件的生命周期
1.什么是组件的生命周期:
组件从被创建到挂载到页面中运行,再到组件不用时卸载的过程
2.钩子函数的作用:
为开发人员在不同阶段操作组件提供了时机。
3.生命周期的意义:
有助于理解组件的运行方式
完成更复杂的组件功能
分析组件错误原因等
4.生命周期使用场景
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">// 1.创建虚拟 dom// 1. 生命周期回调函数 === 生命周期钩子函数 === 生命周期函数 === 生命周期钩子class Person extends React.Component {state = {opacity: 1}constructor(){super();console.log('constructor')}//组件将要挂载componentWillMount(){console.log("componentWillMount")}//组件将要卸载componentWillUnmount(){console.log("啊 我Neo写咋")clearInterval(this.timer)}//组件挂载完成之后componentDidMount() {console.log("componentDidMount")setInterval(() => {// 获取原状态let { opacity } = this.state;opacity -= 0.1;if (opacity <= 0) opacity = 1;//设置新透明度this.setState({ opacity });}, 200)}death=()=>{//卸载组件ReactDOM.unmountComponentAtNode(document.getElementById('test'))}render() {console.log("render")return (<div><span style={{ opacity: this.state.opacity } } >学不会React怎么办</span><button onClick={this.death}>按钮</button></div>)}}// 2.渲染到页面中的指定domReactDOM.render(<Person />, document.getElementById('test'))</script>
</body></html>
5.react 生命周期(旧)
生命周期的三个阶段(旧)
1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
1.constructor()
2.componentWillMount()
3.render()
4.componentDidMount()
2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
1.shouldComponentUpdate()
2.componentWillUpdate()
3.render()
4.componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
1.componentWillUnmount()
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">/*1. 初始化阶段: 由ReactDOM.render()触发---初次渲染1.constructor()2.componentWillMount()3.render()4.componentDidMount() === >常用:一般在这个钩子中做一些初始化的事情:例如:开启定时器,发送网络请求2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发1.shouldComponentUpdate()2.componentWillUpdate()3.render() ===》必须使用4.componentDidUpdate() 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发1.componentWillUnmount() ===》常用一般在中国函数中做一些收尾的事,例如:关闭定时器 取消订阅*/class Person extends React.Component {state = { count: 0 }// 点我add = () => {//获取原状态let { count } = this.state;// 更新状态this.setState({ count: count + 1 });}// 卸载组件death = () => {ReactDOM.unmountComponentAtNode(document.getElementById('test'))}force = () => {this.forceUpdate()}// 数据更新的 '阀门'shouldComponentUpdate = () => {console.log("count ------ shouldComponentUpdate")return true; //这里必须有返回值,其次返回值默认为true}// 组件将要更新的钩子componentWillUpdate() {console.log("count ---- componentWillUpdate")}// 组件更新完毕的钩子componentDidUpdate() {console.log("count ---- componentDidMount")}render() {return (<div><h2>当前求和为:{this.state.count}</h2><button onClick={this.add}>点我+1</button><button onClick={this.death}>卸载组件</button><button onClick={this.force}>不更改任何状态中的数据,强制更新</button></div>)}}// 父组件class A extends React.Component {state = { carName: "电动车" }changeCar = () => {this.setState({ carName: '飞机' });}render() {console.log("render")return (<div><span>我是a组件</span><button onClick={this.changeCar}>换车</button><B carName={this.state.carName} /></div>)}}// 子组件class B extends A {//组件将要接收新的props 的钩子componentWillReceiveProps() {console.log("B ---- componentWillReceiveProps ")}// 数据更新的 '阀门'shouldComponentUpdate = () => {console.log("count ------ shouldComponentUpdate")return true; //这里必须有返回值,其次返回值默认为true}// 组件将要更新的钩子componentWillUpdate() {console.log("count ---- componentWillUpdate")}// 组件更新完毕的钩子componentDidUpdate() {console.log("count ---- componentDidMount")}render() {return (<div>我是b组件,接收到的车是:{this.props.carName}</div>)}}ReactDOM.render(<A />, document.getElementById('test'))</script>
</body></html>
6.React 生命周期(新)
生命周期的三个阶段(新)
- 初始化阶段: 由ReactDOM.render()触发—初次渲染
1.constructor()
2.getDerivedStateFromProps
3.render()
4.componentDidMount()
2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
1.getDerivedStateFromProps
2.shouldComponentUpdate()
3.render()
4.getSnapshotBeforeUpdate
5.componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
1.componentWillUnmount()
<!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>ref</title>
</head><body><!-- 准备好一个容器 --><div id="test"></div><!-- 引入 React 核心库 --><script src="../js/react.development.js"></script><!-- 引入 react-dom 用于支持 react 操作 DOM --><script src="../js/react-dom.development.js"></script><!-- 引入babel:1. ES6 ==> ES52. jsx ==> js--><script src="../js/babel.min.js"></script><script type="text/babel">/*1. 初始化阶段: 由ReactDOM.render()触发---初次渲染1.constructor()2.componentWillMount()3.render()4.componentDidMount() === >常用:一般在这个钩子中做一些初始化的事情:例如:开启定时器,发送网络请求2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发1.shouldComponentUpdate()2.componentWillUpdate()3.render() ===》必须使用4.componentDidUpdate() 3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发1.componentWillUnmount() ===》常用一般在中国函数中做一些收尾的事,例如:关闭定时器 取消订阅*/class Person extends React.Component {state = { count: 0 }// 点我add = () => {//获取原状态let { count } = this.state;// 更新状态this.setState({ count: count + 1 });}// 卸载组件death = () => {ReactDOM.unmountComponentAtNode(document.getElementById('test'))}force = () => {this.forceUpdate()}// 数据更新的 '阀门'shouldComponentUpdate = () => {console.log("count ------ shouldComponentUpdate")return true; //这里必须有返回值,其次返回值默认为true}// 组件将要更新的钩子componentWillUpdate() {console.log("count ---- componentWillUpdate")}// 组件更新完毕的钩子componentDidUpdate() {console.log("count ---- componentDidMount")}render() {return (<div><h2>当前求和为:{this.state.count}</h2><button onClick={this.add}>点我+1</button><button onClick={this.death}>卸载组件</button><button onClick={this.force}>不更改任何状态中的数据,强制更新</button></div>)}}// 父组件class A extends React.Component {state = { carName: "电动车" }changeCar = () => {this.setState({ carName: '飞机' });}static getDerivedStateFromProps(props,state){// 这里必须要一个返回值 ==》 state or null// 这里的state会覆盖原本的状态,并且后续也无法修改// 能将外部的接受的props 赋值给 组件自身的 state// 如果你希望自身的state 一直 全部依赖于外部的props,那么可以使用这个生命周期函数return{carName:'qq'}}// 获取数据getSnapshotBeforeUpDate(prevState,prevProps){}render() {console.log("A --- render")return (<div><span>我是a组件</span><button onClick={this.changeCar}>换车</button><B carName={this.state.carName} /></div>)}}// 子组件class B extends A {//组件将要接收新的props 的钩子componentWillReceiveProps() {console.log("B ---- componentWillReceiveProps ")}// 数据更新的 '阀门'shouldComponentUpdate = () => {console.log("count ------ shouldComponentUpdate")return true; //这里必须有返回值,其次返回值默认为true}// 组件将要更新的钩子componentWillUpdate() {console.log("count ---- componentWillUpdate")}// 组件更新完毕的钩子componentDidUpdate() {console.log("count ---- componentDidMount")}render() {return (<div>我是b组件,接收到的车是:{this.props.carName}</div>)}}ReactDOM.render(<A />, document.getElementById('test'))</script>
</body></html>
7. 重要的勾子
1.render:初始化渲染或更新渲染调用
2.componentDidMount:开启监听, 发送ajax请求
3.componentWillUnmount:做一些收尾工作, 如: 清理定时器
8. 即将废弃的勾子
1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate
现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
总结
以上为react的基础知识,代码里面有注释 。下期出react脚手架。喜欢的话证明自己来过^ - ^
相关文章:

关于React入门基础从哪学起?
文章目录前言一、React简介1. React是什么2. react 与 vue 最大的区别就是:3. React特点4. React介绍描述5. React高效的原因6.React强大之处二、React基础格式1.什么是虚拟dom?2.为什么要创建虚拟dom?三、React也分为俩种创建方式1. 使用js的方式来创建…...

python玄阶斗技--tkinter库
目录 一.tkinter库介绍 二.功能实现 1.窗口创建 2.Button 按钮 3.Entry 文本输入域 4.text 文本框 5.Listbox 多选下拉框 6.Radiobutton 多选项按钮 7.Checkbutton 多选按钮 8.Scale 滑块(拉动条) 9.Scroolbar 滚动条 10.Menu 菜单栏 11. messagebox 消息框 12…...

【MySQL】MySQL的介绍MySQL数据库及MySQL表的基本操作
文章目录数据库的介绍什么是数据库数据库分类MySQL的介绍数据库的基本操作数据库的操作创建数据库查看所有数据库选中指定的数据库删除数据库常用数据类型数值类型字符串类型日期类型表的操作创建表查看指定数据库下的所有表查看指定表的结构删除表小练习数据库的介绍 什么是数…...
【每日随笔】社会上层与中层的博弈 ( 技术无关、没事别点进来看 | 社会上层 | 上层与中层的保护层 | 推荐学习的知识 )
文章目录一、社会上层二、上层与中层的保护层三、推荐学习的知识一、社会上层 社会上层 掌握着 生产资料 和 权利 ; 社会中层 是 小企业主 和 中产打工人 ; 上层 名额有限 生产资料所有者 : 垄断巨头 , 独角兽 , 大型企业主 , 大型企业股东 , 数量有限 ;权利所有者 : 高级别的…...

Cookie 和 Session的区别
文章目录时间:2023年3月23日第一:什么是 Cookie 和 Session ?什么是 Cookie什么是 Session第二:Cookie 和 Session 有什么不同?第三:为什么需要 Cookie 和 Session,他们有什么关联?第四&#x…...

leetcode使用vscode调试C++代码
leetcode使用vscode调试C代码 这里记录一下大体思路吧,关于细节配置放上别的博主的链接,他们讲的更好 vscode只是编辑器,相当于记事本,需要下载minGW提供的编译器和调试器 官方介绍: C/C拓展不包括编译器或调试器&…...

树莓派Linux源码配置,树莓派Linux内核编译,树莓派Linux内核更换
目录 一 树莓派Linux的源码配置 ① 内核源码下载说明 ② 三种方法配置源码 二 树莓派Linux内核编译 ① 内核编译 ② 编译时报错及解决方案(亲测) 三 更换树莓派Linux内核 操作步骤说明 ● dmesg报错及解决方案(亲测࿰…...
【C语言】深度讲解 atoi函数 使用方法与模拟实现
文章目录atoi使用方法:atoi模拟实现atoi 功能:转化字符串到整数 头文件: #include <stdlib.h> int atoi (const char * str); 参数 str:要转换为整数的字符串 返回值 如果转换成功,函数将转换后的整数作为int值…...

HTTPS的加密流程
1、概念HTTPS 是一个应用层协议,是在 HTTP 协议的基础上引入了一个加密层。HTTP 协议内容都是按照文本的方式明文传输的,这就导致在传输过程中出现一些被篡改的情况。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协…...

STM32配置读取BMP280气压传感器数据
STM32配置读取BMP280气压传感器数据 BMP280是在BMP180基础上增强的绝对气压传感器,在飞控领域的高度识别方面应用也比较多。 BMP280和BMP180的区别: 市面上也有一些模块: 这里介绍STM32芯片和BMP280的连接和数据读取。 电路连接 BMP28…...

【Linux】 基础IO——文件(中)
文章目录1. 文件描述符为什么从3开始使用?2. 文件描述符本质理解3. 如何理解Linux下的一切皆文件?4. FILE是什么,谁提供?和内核的struct有关系么?证明struct FILE结构体中存在文件描述符fd5. 重定向的本质输出重定向输…...

蓝桥杯刷题冲刺 | 倒计时13天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.母牛的故事2.魔板1.母牛的故事 题目 链接: [递归]母牛的故事 - C语言网 (dotcpp.c…...

MIPI D-PHYv2.5笔记(5) -- 不同的PHY配置方式
声明:作者是做嵌入式软件开发的,并非专业的硬件设计人员,笔记内容根据自己的经验和对协议的理解输出,肯定存在有些理解和翻译不到位的地方,有疑问请参考原始规范看 规范5.7章节列举了一些常见的PHY配置,但实…...

【周末闲谈】文心一言,模仿还是超越?
个人主页:【😊个人主页】 系列专栏:【❤️周末闲谈】 周末闲谈 ✨第一周 二进制VS三进制 文章目录周末闲谈前言一、背景环境二、文心一言?(_)?三、文心一言的优势?😗😗😗四、文心一…...

《一“企”谈》 | 「佛山市政」:携手企企通,让采购业务数智化
近日,国家施工总承包壹级企业「佛山市市政建设工程有限公司」(以下简称“佛山市政”)正积极布局数字化建设工作,基于采购业务数智化,携手企企通打造了SaaS采购云平台。 01、岭南建筑强企 匠心铸造精品 …...

Spark运行架构
目录 1 运行架构 2 核心组件 2.1 Driver 2.2 Executor 2.3 Master & Worker 2.4 ApplicationMaster 3 核心概念 3.1 Executor 与 Core 3.2 并行度( Parallelism) 3.3 有向无环图( DAG) 4 提交流程 …...

基于卷积神经网络CNN的水果分类预测,卷积神经网络水果等级识别
目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络CNN水果分类预测 基本结构 主要参数 MATALB代码 结果图 展望 背影 现在生活,为节能减排,减少电能…...
Spring Boot 框架总结
Spring Boot 框架总结 1. springboot的引言 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的 初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不 再需要定义样板化的配置。通过这种方式࿰…...

【数据结构】第五站:带头双向循环链表
目录 一、链表的八种结构 二、带头双向循环链表的实现 1.链表的定义 2.链表的接口定义 3.接口的具体实现 三、带头双向循环链表的完整代码 四、顺序表和链表的区别 一、链表的八种结构 我们已经知道链表可以有以下三种分法 而这三种结构又可以排列组合,形成八…...
Springboot生成二维码
Springboot生成二维码整合 我们使用两种方式,去生成二维码,但是其实,二维码的生成基础,都是zxing包,这是Google开源的一个包,第一种是使用原始的zxing方式去实现,第二种是使用hutool来实现&…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...