React学习笔记

2023-11-07

一、基础

1.概念

React是用于构建用户界面的JavaScript库(只关注视)

2.特点

声明式编程:React 使创建交互式 UI ,当数据变动时 React 能高效更新并渲染合适的组件。

组件化: 构建管理自身状态的封装组件,然后对其组合以构成复杂的 UI。

高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。

灵活:无论你现在使用什么技术栈,都可通过引入 React 来开发新功能。

3.高效原因

使用虚拟(virtual)DOM,不总是直接操作页面真实DOM。
DOM Diffing算法,最小化页面重绘
说明:React并不会提高渲染速度,反而可能会增加渲染时间,真正高效的原因是它能有效减少渲染次数

4.虚拟DOM

本质时Object类型的对象(一般对象)
虚拟DOM比较’轻’,真实DOM比较’重’,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性(只有React需要的属性)
虚拟DOM最终会被React转化为真实DOM,呈现在页面上

5.初步使用React

1、首先创建一个html文件,用IDE工具打开,引入react核心库 、react 扩展库、编译jsx为js的库,如下

<!-- react核心库 -->
<script src="js/react.development.js"></script>
<!-- react 扩展库 操作dom元素 -->
<script src="js/react-dom.development.js"></script>
<!-- 编译jsx的一个语法 -->
<script src="js/babel.min.js"></script>

2、在html文件中创建一个容器,然后创建虚拟DOM并渲染到页面上,代码如下

<div id="demo"></div>
<script type="text/babel">
		  //创建虚拟DOM 1如果是单行 不需要加()如果是多行用()
		   let str = "hello,react";
		   //混入js表达式用{},class样式用className
		   const VDEMO =(
		     <h111 className="demo" style={{background:'red',color:'green',fontSize:'40px'}}>
				 <span>{str}</span>
				 <p>{str}</p>
		     </h111>
		   )
		   //渲染虚拟dom到页面上
		   ReactDOM.render(VDEMO,document.getElementById("demo"));
		</script>

注意此处的script便签要注明类别,因为我们用的是jsx语法
3、hello,react成功出现在页面上

6.jsx语法规则

JSX是一种JavaScript的语法扩展、是一种嵌入式的类似XML的语法,常应用于React架构中,但也不仅限于此.
语法规则:
1、定义虚拟DOM时不要用引号
错误示例:

let V_DOM =<h1>hello,react</h1>;

2、标签混入JS表达式需要用{}
举例:

let str  = "hello,react!";
let V_DOM = (
		      <h1><span>{str}</span></h1>
)

3、样式的类名指定不要用class,要用className
示例:

let V_DOM = (
	<h1 className='demo'><span>我是文本内容</span></h1>
)

4、内联样式要用style={{key:value}}的形式(双{}代表对象,单{}代表表达式)去写。
示例:

 let V_DOM = (
<h1 className='demo'><span style={{color:'blue',fontSize:'30px'}}>我是文本内容</span></h1>
 )
ReactDOM.render(V_DOM,document.getElementById("hello"));

5、只有一个根标签
错误形式:

 let V_DOM = (
<h1 className='demo'><span style={{color:'blue',fontSize:'30px'}}>我是文本内容</span></h1>
<p>我是段落</p>
 )

6、标签必须闭合
举例:

<input type=”text” name=’myname’ value=’’></input>

7、标签首字母
小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错
大写字母开头,react就去渲染对应组件,若组件没有定义,则报错
8、不能放在创建虚拟dom语句中的js语句
if(){}
for(){}
switch(){}

二、组件

1、函数式组件

基本应用:

 function Person(){
			   // console.log(typeof obj.age);//查看类型
			   return <h1>姓名:张三,年龄:19</h1>
		   }
ReactDOM.render(<Person/>,document.getElementById('demo'));

组件传参:

 function Person(obj){
			   // console.log(typeof obj.age);//查看类型
			   return <h1>姓名:{obj.name},年龄:{obj.age}</h1>
		   }
ReactDOM.render(<Person name="张三" age={19}/>,document.getElementById('demo'));

组件复用:

 function GetName(obj){
				 return <li>姓名:{obj.name}</li>
			 }
 function GetAge(obj){
				 return <li>年龄:{obj.age}</li>
			 }
function Person(){
				 return (
				    <ul>
					    <GetName name='张三'/>
						<GetAge age='19'/>
					</ul>
				 )
			 }
 ReactDOM.render(<Person/>,document.getElementById('demo'));

2、类式组件

1:继承react中的Component类
2:需要render
基本应用:

class Person extends React.Component{
			 render(){
				 return (
				     <h1>你好,我是类式组件!</h1>
				 )
			 }
}
ReactDOM.render(<Person/>,document.getElementById("hello"));

小例子:

class Item extends React.Component {
				data = [
					{ name: '张三', age: 11, index: 0 },
					{ name: '李四', age: 12, index: 1 },
					{ name: '王五', age: 13, index: 2 },
					{ name: '铁柱', age: 14, index: 3 },
					{ name: '李华', age: 15, index: 4 },
					{ name: '李明', age: 16, index: 5 },
				]
				render() {
					return this.data.map(v => {
						return (
							<li
								key={v.index}
								className={v.index % 2 == 0 ? 'oushu' : 'jishu'}
							>
								姓名:{v.name}——年龄:{v.age}{' '}
							</li>
						)
					})
				}
			}
			class Person extends React.Component {
				name = '111'
				render() {
					return (
						<ul>
							<Item />
						</ul>
					)
				}
			}
			//渲染虚拟dom到页面上
			ReactDOM.render(<Person />, document.getElementById('demo'))

三、组件实例的三大属性

1、state

概念:state是组件对象最重要的属性,值是对象(可以包含多个key:value的组合),组件被称为状态机,通过更新组件的state来更新对应的页面显示(重新渲染组件),有state称为复杂组件。
State 的使用对象形式(key,value);
代码:

class MyClass extends React.Component{
  constructor(props) {   
  		   super(props);
  		   this.state = {isflag:true};
  }
  render(){
  	return <a href='javascript:;' className='btn'>{this.state.isflag?'已关注':'取消关注'}</a>
  }
}
ReactDOM.render(<MyClass/>,document.getElementById('hello'));

react绑定事件:
说明:
·onclick 变为 onClick。
·{函数名}返回值给click,加()就会直接调用。
例:

render(){
return <a href='javascript:;' onClick={demo} className='btn'>{this.state.isflag?'已关注':'取消关注'}</a>
}

修改state值:

 class MyClass extends React.Component{
constructor(props) {   
			   super(props);
			   this.state = {isflag:true};
			   this.demo = this.demo.bind(this);
}
render(){
	return <a href='javascript:;' onClick={this.demo} className='btn'>{this.state.isflag?'已关注':'取消关注'}</a>
}
demo(){
	this.setState({isflag:!this.state.isflag})
}
}
 ReactDOM.render(<MyClass/>,document.getElementById('hello'));

说明:
·bind会生成一个新的方法 并传对象 改变this的指向
·必须使用setState 修改才有效,修改内容为合并。有值得修改没有的不动

2、props

· 每个组件对象都会有props(properties的简写)属性。
· 组件标签的所有属性都保存在props中。
· props 是不可变的,只能通过 props 来传递数据。

 class Person extends React.Component{
			   render(){
                const {name,age} = this.props;
				   return (
					   <ul>
						  <li>姓名:{name}</li>
						  <li>年龄:{age}</li>
						</ul>
				   )
				     }
		   }
ReactDOM.render(<Person name='张三' age='18'/>,document.getElementById('hello'));

propTypes参数的限制:
需要引入依赖包:

 class Person extends React.Component{
			   render(){
                const {name,age,sex} = this.props;
				   return (
					   <ul>
						  <li>姓名:{name}</li>
						  <li>年龄:{age}</li>
						  <li>性别:{sex}</li>
						</ul>
				   )
			   }
			   static propTypes = {
				   name:PropTypes.string.isRequired,//必填且为字符串型
				   age:PropTypes.number,//数值型
			   }
			   static defaultProps = {
				   sex:'未知',
			   }
 }

3、refs

定义:组件内的标签可以定义ref来标识自己。
ref有三种用法:
1):字符串形式的ref

 class MyRefs extends React.Component{
  showData = ()=>{
			  		//字符串形式的ref
					let input1 = this.refs.input1;
					alert(input1.value);
		 }
showData2 = ()=>{
				  let input2 = this.refs.input2;
				  alert(input2.value);
		}
render(){
	return (
		<div> <input ref="input1" type="text" placeholder="点击时提示信息" /><br/><br/>
						<input onClick={this.showData} type="button" value="点击显示信息"/><br/><br/>
                        <input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点时显示信息" />
					 </div>
				  )
			  }
		  }
}

2):回调函数形式的ref

 class Demo extends React.Component{
			  showData = ()=>{
			  		//回调函数下创建ref
				    const {input1}=this;
					console.log(input1.value);
			  }
			  showData2 = ()=>{
				 const {input2}=this;
				 console.log(input2.value);
			  }
			  render(){
				  return (
					 <div>
					    <input ref={c=> this.input1 = c} type="text" placeholder="点击时提示信息" /><br/><br/>
						<input onClick={this.showData} type="button" value="点击显示信息"/><br/><br/>
                        <input ref={c=> this.input2 = c} onBlur={this.showData2} type="text" placeholder="失去焦点时显示信息" />
					 </div>
				  )
			  }
		  }

3):类绑定形式下ref

 class MyRefs extends React.Component{
 userInput = React.createRef();
 passInput = React.createRef();
  showData = ()=>{
					//createRef创建ref 官方推荐
					 const {userInput,passInput} = this;
					 const str = `用户名是${userInput.current.value},密码是:${passInput.current.value}`;
					 console.log(str);
				 }
				 //显示个性签名
 showmessage = (e)=>{
					 console.log('message:',e.target.value);
				 }
 render(){
					 return (
							<div>
							<ul className="list">
							   <li><input ref={this.userInput} type="text" placeholder="请输入用户名"/> </li>
								<li><input ref={this.passInput} type="password"  placeholder="请输入密码"/> </li>
								<li><input type="button" onClick={this.showData} value="查看信息"/> </li>
							   <li><input  type="text" onKeyUp ={this.showmessage}   placeholder="请输入个性说明"/> </li>
							</ul>
							</div>
					 )
				 }
}

四、受控组件和非受控组件

1、非受控组件

class Control extends React.Component {
				showdata = () => {
					// 现取现用,非受控组件
					console.log(this.name.value)
					console.log(this.age.value)
				}
				render() {
					return (
						<ul>
							<li>
								<input
									type="text"
									ref={e => (this.name = e)}
								></input>
							</li>
							<li>
								<input
									type="text"
									ref={e => (this.age = e)}
								></input>
							</li>
							<button onClick={this.showdata}>显示数据</button>
						</ul>
					)
				}
			}

2、受控组件

class Control1 extends React.Component {
				state = { name: '', age: '' }
                // 将值存储到state里面,按需取用,受控组件
				saveName = e => {
					// console.log(e.target.value)
                    this.setState({name:e.target.value})
				}
				saveAge = e => {
					// console.log(e.target.value)
                    this.setState({age:e.target.value})
				}
                showdata=()=>{
                    console.log(this.state)
                }
				render() {
					return (
						<ul>
							<li>
								<input
									type="text"
									onChange={this.saveName}
								></input>
							</li>
							<li>
								<input
									type="text"
									onChange={this.saveAge}
								></input>
							</li>
							<button onClick={this.showdata}>显示数据</button>
						</ul>
					)
				}
			}

五、高阶函数处理

高阶函数
定义:如果一个函数符合下面两个规范中的任何一个,那该函数就是高阶函数
·若A函数,接受的参数是一个函数,那么A就可以称之为高阶函数
·若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数
常见的高阶函数有:Promise、setTimeout、arr.map()等等
代码示例:

 class Demo extends React.Component{
                //初始化状态
               state = {username:'',password:''};
			   savedata = (dataType)=>{
				   return (event)=>{
					   this.setState({[dataType]:event.target.value});
				   }
			   }
				
             showdata = (event)=>{
				 event.preventDefault();//阻止默认事件
				let {username,password} = this.state;
				alert(username + '-' + password);
			 }
			 render(){
				 return (
				    <form action="" onSubmit={this.showdata}>
				     用户名: <input onChange={this.savedata('username')} type="text" name="username"/><br/>&nbsp;&nbsp;&nbsp;&nbsp;码:<input onChange={this.savedata('password')} type="password" name="password"/><br/>
					   <input type="submit" name="dosubmit" value="提交信息"/>
					</form>
				 );
			 }
		 }

分析上面的代码,会发现组件内的绑定事件后面加了括号传值,而前面的语法部分说了方法名后面加了括号就是直接调用执行,这时候就体现高阶函数的作用了,我们把函数单独拿出来

 savedata = (dataType)=>{
				   return (event)=>{
					   this.setState({[dataType]:event.target.value});
				   }
			   }

注意看函数的返回值,返回了一个函数,所以绑定事件直接调用之后返回了一个函数,这个函数才是我们需要去出触发的方法,我们做的只是用同一个函数根据不同的传值来返回代码几乎一样的方法,节省了代码量

六、生命周期

·组件从创建到死亡,会经过一些特定的阶段。
·React组件中包含一系列钩子函数{生命周期回调函数},会在特定的时刻调用。
·我们在定义组件的时候,会在特定的声明周期回调函数中,做特定的工作。

1、生命周期(旧)

1):初始化

由ReactDOM.render()触发,一般在这个钩子中做一些初始化的事情,如:开启定时器,发送网络请求,订阅消息等。
·constructor() 构造方法:构造函数最先执行,用处:进行初始化的一些数据
·componentWillMount() 即将挂载
·render() 组件渲染
·componentDidMount() ==>常用 组件将要渲染

2):更新阶段

由组件内部的this.setState()或者父组件的render触发。
·shouldComponentUpdate() 组件应该更新:阀门,当更新的时候,受其控制,true就让更新,false就不让更新

shouldComponentUpdate(){
					console.log("Count shouldCompenentUpdate---");
					return true;
				}

·componentWillUpdate() 组件将要更新
·render() ===>必须使用的一个
·componentDidUpdate() 组件将要更新

3):卸载组件

由ReactDOM.unmountComponentAtNode(卸载节点上的组件)触发,一般在这个钩子中做一些首位的事情,如:关闭定时器,取消订阅等

2、生命周期(新)

1):初始化

·constructor()
· getDerivedStateFromProps()
state里面的内容由props控制。如果全部控制 就return props 部分更改,return对象里面写要更改的数据
在render之前调用
此钩子 是静态方法 必须有返回值

static getDerivedStateFromProps(props){
					console.log("Count getDerivedStateFromProps----");
					return {title:props.title};
				}

·render()
·componentDidMount() ====>常用

2):更新阶段

·getDerivedStateFromProps() 从Props获得派生状态
· shouldComponentUpdate() 组件应该更新
·render()
·getSnapshotBeforeUpdate() 在更新前获得快照
·componentDidUpdate()

3):卸载组件

由ReactDOM.unmountComponentAtNode()触发

  • componentWillUnmount() ===>常用
    一般在这个钩子中做一些收尾的事情,如:关闭定时器、取消订阅消息

总结

1、重要的钩子

  1. render:初始化渲染或者更新渲染调用
  2. componentDidMount() :开启监听,发送ajax请求
componentDidMount(){
					let {count} = this.state;
					this.myinter = setInterval(()=>{
						count++;
						this.setState({count:count})
					},1000)
				}
  1. componentWillUnmount(): 做一些收尾工作,如:清理定时器
 componentWillUnmount(){
				   //清除定时器
				 clearInterval(this.myinter);
			   }

2、即将废弃的钩子

  1. componentWillMount
  2. componentWillReceiveProps
  3. componentWillUpdate
    ps:现在使用会出现警告,之后版本可能需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用
    推测React团队认为提高使用成本将会间接影响我们,让我们去适应新的钩子,所以加上这个
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React学习笔记 的相关文章

  • dojo dijit.form.DateTextBox 约束不起作用,datetextbox

    嗨 我是 javascript 和 dojo 的新手 我正在尝试使用两个带有下拉日历的 dijit DateTextBox 来建立数据库查询的日期范围 一旦选择了开始日期或结束日期 我想限制可用的日期 以便不可能选择按时间顺序排列在开始日期
  • TypeError: props.render 不是一个函数(React hook 形式)

    我将方法作为我用react hook form制作的形式的道具传递 当从react hook form添加控制器时 它给了我 TypeError props render不是一个函数 我在网上找不到任何解决方案 因此感谢任何帮助 impor
  • 使用 useReducers 调度函数发送多个操作?

    使用时是否可以通过调度函数发送多个动作useReducer挂钩反应 我尝试向它传递一组操作 但这会引发未处理的运行时异常 明确地说 通常会有一个初始状态对象和一个减速器 如下所示 const initialState message1 nu
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 检查 JavaScript 字符串是否为 URL

    JavaScript 有没有办法检查字符串是否是 URL 正则表达式被排除在外 因为 URL 很可能是这样写的stackoverflow 也就是说它可能没有 com www or http 如果你想检查一个字符串是否是有效的 HTTP UR
  • Meteor:应用程序无法在 0.9.1.1 版本上运行

    出现类似错误 Error TypeError undefined is not a function evaluating Template create anonymous function iron dynamic template j
  • 在 Wordpress 站点中进行 AJAX 调用时出现问题

    我在使用 Wordpress 站点功能的 AJAX 部分时遇到了一些问题 该功能接受在表单上输入的邮政编码 使用 PHP 函数来查找邮政编码是否引用特定位置并返回到该位置的永久链接 我的第一个问题是关于我构建的表单 现在我的表单操作是空白的
  • 如何抑制窗口鼠标滚轮滚动...?

    我正在开发嵌入页面中的画布应用程序 我有它 因此您可以使用鼠标滚轮放大绘图 但不幸的是 这会滚动页面 因为它是文章的一部分 当我在 dom 元素上滚动鼠标滚轮时 是否可以阻止鼠标滚轮在窗口上滚动 附加鼠标滚轮 不是 Gecko DOMMou
  • 音频 blob 的 URL.createObjectURL 在 Firefox 中给出 TypeError

    我正在尝试从创建的音频 blob 创建对象 URLgetUserMedia 该代码在 Chrome 中可以运行 但在 Firefox 中存在问题 错误 当我打电话时stopAudioRecorder 它停在audio player src
  • 如何将 Google Charts 与 Vue.js 库一起使用?

    我正在尝试使用 Vue js 库使用 Google Charts 制作图表 但我不知道如何添加到 div 这是我尝试做的 这是如何使用普通 javascript 添加图表 这是文档的代码示例 https developers google
  • 跟踪用户何时点击浏览器上的后退按钮

    是否可以检测用户何时单击浏览器的后退按钮 我有一个 Ajax 应用程序 如果我可以检测到用户何时单击后退按钮 我可以显示适当的数据 任何使用 PHP JavaScript 的解决方案都是优选的 任何语言的解决方案都可以 只需要我可以翻译成
  • 表单计算器脚本基本价格未加载 OnLoad

    我的表单中有一个计算器来计算我的下拉选项选择 function select calculate on change calc input type checkbox calculate on click calc function cal
  • 通过 CDN 使用 Dojo 时如何加载自定义 AMD 模块?

    我正在使用 google 的 CDN 并尝试使用他们的加载程序加载我自己的 AMD 模块 我知道我做错了什么 但我被困住了 有任何想法吗
  • Angular 2+ 安全性;保护服务器上的延迟加载模块

    我有一个 Angular 2 应用程序 用户可以在其中输入个人数据 该数据在应用程序的另一部分进行分析 该部分仅适用于具有特定权限的人员 问题是我们不想让未经授权的人知道how我们正在分析这些数据 因此 如果他们能够在应用程序中查看模板 那
  • 如何使用tampermonkey模拟react应用程序中的点击?

    我正在尝试使用 Tampermonkey 脚本模拟对 React 元素的点击 不幸的是 由于 React 有自己的影子 DOM 所以天真的方法使用document querySelector 不工作 我遇到了一些需要修改 React 组件本
  • 为什么我不能在 AngularJS 中使用 data-* 作为指令的属性名称?

    On the t他的笨蛋 http plnkr co edit l3KoY3 p preview您可以注意到属性名称模式的奇怪行为data 在指令中 电话 Test of data named attribute br
  • Javascript 纪元时间(以天为单位)

    我需要以天为单位的纪元时间 迄今为止 我已经看到过有关如何翻译它的帖子 但几天后就没有了 我对纪元时间很不好 我怎么能得到这个 我需要以天为单位的纪元时间 我将解释为您想要自纪元以来的天数 纪元本身是第 0 天 或第 1 天的开始 无论您如
  • Safari 支持 JavaScript window.onerror 吗?

    我有一个附加到 window onerror 的函数 window onerror function errorMsg url line window alert asdf 这在 firefox chrome 和 IE 中工作正常 但在 s
  • JQuery 图像上传不适用于未来的活动

    我希望我的用户可以通过帖子上传图像 因此 每个回复表单都有一个上传表单 用户可以通过单击上传按钮上传图像 然后单击提交来提交帖子 现在我的上传表单可以上传第一个回复的图像 但第二个回复的上传不起作用 我的提交过程 Ajax 在 php 提交
  • 使用 Ajax 请求作为源数据的 Jquery 自动完成搜索

    我想做的事 我想使用 jquery 自动完成函数创建一个输入文本字段 该函数从跨域curl 请求获取源数据 结果应该与此示例完全相同 CSS 在这里并不重要 http abload de img jquerydblf5 png http a

随机推荐