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学习笔记 的相关文章

  • 在 ajax 完成之前阻止提交

    我正在使用 jQuery 并且我希望在所有 ajax 调用完成之前表单提交不会起作用 我想到的一种方法是存储一个布尔值 该值指示是否有 ajax 请求正在进行 在每一个结束时它都会被设置为 false 我不确定这是否是最好的方法 所以我将不
  • 从 x,y 屏幕空间坐标查找 2D 等距网格上的列、行(将方程转换为函数)

    我试图在屏幕空间点 x y 的二维等距网格中找到行 列 现在我几乎知道我需要做什么 即找到上图中红色向量的长度 然后将其与表示网格边界的向量的长度 由黑色向量表示 进行比较 现在我在数学堆栈交换中寻求帮助 以获得用于计算点 x y 与黑色边
  • 为什么 jQuery 点击事件会多次触发

    我这里有这个示例代码http jsfiddle net DBBUL 10 http jsfiddle net DBBUL 10 document ready function creategene click function confir
  • 将 jquery-mobile 与 Webpack 结合使用

    我正在尝试使用 webpack 加载 jquery mobile 但到目前为止还没有运气 我知道 jquery mobile 依赖于 jquery ui 而 jquery ui 又依赖于 jquery 如何在 Webpack 中设置这样的场
  • Flask wtf.quick_form 运行一些 javascript 并设置表单变量

    我正在创建博客文章 到目前为止已经使用普通的 html 表单完成了 我所做的一个有趣的想法是运行 javascript onclick 并使用页面中的额外数据在表单中设置一个隐藏变量 这很好地传递到服务器并通过 request form 获
  • 将 Sweet Alert 弹出窗口添加到 React 组件中的按钮

    我为 Bootstrap 和 React 找到了这个完美的 Sweet Alert 模块 我在 Meteor 应用程序中使用它 http djorg83 github io react bootstrap sweetalert http d
  • 响应式网格布局框架[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 创建 Cookie 时需要帮助

    我有一个名为yes和另一个名叫no
  • 使用模态表单 ajax 超出 HTMLFormElement.toString 的最大调用堆栈大小

    我想使用模态窗口中的 ajax 请求提交表单 单击此链接可打开该模式 a class btn btn primary i class fa fa edit i Write a review a 模态窗口 div class modal fa
  • ElectronJS ReferenceError:导航器未定义

    我正在尝试在电子上制作自定义标题栏 但是当我启动我的应用程序时 我遇到了 ReferenceError 导航器未定义 问题 请帮忙 这是我的 main js 中的代码片段 My Codes https i stack imgur com c
  • Ember.JS - 如何在同一页面中使用多个模型、控制器和视图?

    我主要了解 Ember JS 的基础知识 大多数示例实际上只处理单个控制器和模型以在页面上显示某些内容 我真的很想用 Ember 构建一个完整的 Web 应用程序 所以有人能告诉我如何组织和连接多个控制器 模型和视图到一个页面中吗 例如 如
  • iframe 重新加载按钮

    我浏览了很多网站 但似乎没有一个能正常工作 或者我不明白它们 我想要一个刷新某个 iframe 的简单按钮 该按钮将位于父页面上 并且 iframe 名称为 Right 有很多方法可以做到这一点 假设这个iframe markup 我们可以
  • v-file-input .click() 不是函数

    我试图以编程方式触发 v file input 的 click 事件 因为它在 Vuetify 的文档中 但它显示一个错误this refs imagePicker click is not a function我在这里错过了什么吗 代码重
  • KeyboardEvent.keyCode 已弃用。这在实践中意味着什么?

    根据 MDN 我们绝对应该not正在使用 keyCode财产 它已被弃用 https developer mozilla org en US docs Web API KeyboardEvent keyCode https develope
  • 访问 TypeScript 数组的最后一个元素

    TypeScript 中有访问数组最后一个元素的符号吗 在 Ruby 中我可以说 array 1 有类似的东西吗 您可以通过索引访问数组元素 数组中最后一个元素的索引将是数组的长度 1 因为索引是从零开始的 这应该有效 var items
  • 如何清除WebGL中的矩形区域?

    WebGL 有一个clear清除整个表面的方法 清除表面的特定矩形的最佳方法是什么 例如 我想将一个从 50 50 开始的 100x100 像素框设置为全零 ARGB 0 0 0 0 我现在能想到的就是用一个写入零的片段着色器绘制一个四边形
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • window.showModalDialog 的等效跨浏览器解决方案是什么?

    window showModalDialog 的等效跨浏览器解决方案有哪些 showModalDialog 在 IE 和 FF 3 中引入 我个人认为没有 但是有很多 UI 工具包提供了这样的功能 例如jQuery UI http jque
  • ng-model 和值组合不适用于输入文本框

    我有两个输入文本框 我需要组合在两个文本框中输入的值并将其显示在第三个文本框中 如果我只使用value在第三个文本框中 Box 1
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e

随机推荐