前言:最近跟着教程把react相关的教程过了一遍,本专栏博客是为了系统的梳理一下相关的内容知识点,将保持在每周2-3篇的更新频率,系统的将react的知识内容复习一遍,其中穿插着一些和js相关的补充知识点有助于对js的强化。纯属个人笔记内容记录,如有错误之处,还望大家在评论区留言指正。
一、JSX基础语法规则
1.1 什么是JSX?
什么是JSX呢?JSX是一种JavaScript的语法扩展,运用于React架构中,其格式比较像是模版语言,但事实上完全是在JavaScript内部实现的。元素是构成React应用的最小单位,JSX就是用来声明React当中的元素,React使用JSX来描述用户界面。
const elemnet=<h1>今天是学习react的第一天</h1>;
上面就是典型的JSX语法格式的代码,究其本质而言是为我们提供了创建React元素原始方法React.createElement(component,props,..children)的语法糖,上面的代码实质上等价于以下代码:
const element=React.createElement("h1",null,"今天是学习react的第一天");
实际上,JSX本身也是一个表达式,在编译后,JSX表达式会变成普通的JavaScript对象。你可以在if语句或for循环中使用JSX,你可以将它赋值给变量,你可以将它作为参数接收,你也可以在函数中返回JSX。比如下面的代码:
function eat(food){
return food==="apple"?<h2>今天吃apple了</h2>:<h2>今天没吃到apple</h2>;
}
1.2 react中需要了解的JSX语法规则
1、在使用JSX定义虚拟dom时,不要写引号,单引号和双引号都不需要添加。
2、在JSX的标签中混入JS表达式时需要使用到{},也就是大括号。
3、标签内的样式类名应该使用的是className,而不是class。
4、标签的内联样式,应该使用style={{key:value}}的形式去写。
5、应该只有一个根标签,也就是所有其他的标签都必须包裹在根标签里面。
6、标签的首字母:
1)若小写字母开头,则将此标签转为html中同名元素,若html中无此标签对应的同名元素,则会报错。
2)若为大写字母开头,react就去渲染对应的组件,若组件不存在就会报错。
1.3 JavaScript中的语句和表达式的区别(补充)
1、所谓表达式:就一定会产生一个具体的值。可以放在任何一个需要值得地方去使用。
//下面这些都是表达式
a;
a+b;
demo(1);
arr.map();
function test(){};
2、所谓语句(代码):和表达式相对,无返回具体的值,只是作为功能作用。
//下面这些都是语句
if(){};
for(){};
switch(){case:xxxx};
二、函数式组件和类式组件
2.1 函数式组件和类式组件的定义
一个函数就是一个组件,函数组件的结构如下:
//创建函数式组件
function MyComponent(){
return <div>我是使用函数定义的组件</div>
}
//渲染组件到页面中
ReactDom.render(<MyComponent/>,document.getElementById('root'));
//render方法执行后发生了什么呢?
//1、React解析组件标签,找到了MyComponent组件。
//2、发现组件是使用函数定义的,随后调用该函数,将返回的虚拟DOM转为真实DOM。随后呈现在页面中去。
相比较于函数式的组件,类式组件的结构就相对复杂一点,类式组件之间可以通过extends存在着继承关系,包括类中的构造函数。
简单的类式组件如下所示:
//1 创建类式组件,类组件默认是从React.Component中继承而来的;
class MyComponent extends React.Component{
//构造函数可在需要给对象实例传递初始值的时候进行添加使用。
constructor(){
super(props);
}
//类式组件通过render方法返回虚拟dom,render在类的原型对象上,供实例使用。
//render的this指向的是类式组件的实例对象。
render(){
return <h2>我是通过类定义的组件</h2>
}
}
//渲染组件到页面中
ReactDom.render(<MyComponent/>,document.getElementById('test'));
//相比较于函数式组件直接将返回的虚拟dom渲染到页面上,类式组件需要先new出一个类的实例,再通过该实例方法去调用原型上的render方法。
2.2 state,props和refs
2.2.1 state
state顾名思义就是状态,react中页面的变化是由状态驱动的,因此状态的重要性不言而喻,在类式组件中我们可以直接使用state,而函数式的组件中我们需要借用hooks function来操作state。state应该写在类式组件的开始,便于后面使用,且不一定要写在构造函数里面。
<!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>React Learning</title>
</head>
<body>
<div id="test">
</div>
//此处省略掉所需要引用的React三个模块 React\React-dom\bable,
<script type="text/babel">
//1 创建组件
class Weather extends React.Component{
constructor(props){
super(props)
//state不一定要在构造函数内生命,其默认是一个对象。
this.state={isHot:true}
}
render(){
//对state进行结构赋值
const {isHot}=this.state
return <h2>今天温度很高{isHot?'炎热':'凉爽'}<h2/>
}
}
//2 渲染组件到页面
ReactDOM.render(<Weather/>,document.getElementById('test'))
</script>
</body>
</html>
JavaScript中的原生事件绑定方式:声明了状态state,状态驱动页面的更新,我们就需要去在标签内绑定相关事件通过setState改变组件的状态,那么原生JS中有哪些事件绑定方式呢?以及常见的事件有哪些呢?state中的数据不可以直接进行修改,需要通过setState()方法进行修改,对于状态的修改,其本质上是状态的合并行为。
//1 在原生dom中直接绑定
<input οnclick="alert('记得点赞')" type="button" value="点击我,弹出警告框" />
//2 原生dom中采用自定义函数形式
<input οnclick="myAlert()" type="button" value="点击我,弹出警告框" />
<script type="text/javascript">
function myAlert(){
alert("记得点赞");
}
</script>
//2 获取元素后,在js中绑定事件,好处是可以实现JS代码和html标签的分离,便于管理和维护
<input id="demo" type="button" value="点击我,显示 type 属性" />
<script type="text/javascript">
document.getElementById("demo").οnclick=function(){
alert(this.getAttribute("type")); // this 指当前发生事件的HTML元素,这里是<div>标签
}
</script>
//3 绑定事件的监听函数
// 使用addEventListener()和attachEvent()函数
<input id="demo" type="button" value="点击我,显示 type 属性" />
<script type="text/javascript">
let demo=document.getElementById("demo");
demo.addEventListener("click",alert(this.getAttribute("type")));
// this 指当前发生事件的HTML元素,这里是<div>标签
</script>
JavaScript原生事件绑定方式汇总
原生JavaScript的常见事件
1.点击事件:
onclick:单击事件
ondblclick:双击事件
2.焦点事件
onblur:失去焦点
onfocus:元素获得焦点。
3.加载事件:
onload:一张页面或一幅图像完成加载。
4.鼠标事件:
onmousedown 鼠标按钮被按下。
onmouseup 鼠标按键被松开。
onmousemove 鼠标被移动。
onmouseover 鼠标移到某元素之上。
onmouseout 鼠标从某元素移开。
5.键盘事件:
onkeydown 某个键盘按键被按下。
onkeyup 某个键盘按键被松开。
onkeypress 某个键盘按键被按下并松开。
6.选择和改变
onchange 域的内容被改变。
onselect 文本被选中。
7.表单事件:
onsubmit 确认按钮被点击。
onreset 重置按钮被点击。
JavaScript原生事件
第三种绑定事件监听函数的两个方法的语法如下:
实际上,以上三种事件绑定的方式在react中均有效,我们一般选择第一种直接在标签内绑定事件函数。不同的是,事件的绑定名采用小驼峰的命名方式,比如onClick.....
关于state的总结要点如下:
//总结state相关内容
//是组件对象的最重要的属性,值是对象,即多个Key-value的组合
//1 组件中的render方法中的this为组件实例对象。
//2 组件中自定义方法中的this默认为undefined,可以通过bind修改this的指向,或配合赋值语句加箭头函数。
//3 state中的数据不可以直接进行修改,需要借助对应的API中的setState()
2.2.2 props
props的作用是收集ReactDom创建组件实例对象时标签内设置的key-value,收集到key-value经过结构赋值后直接在标签体内进行展示,并且可以实现父子组件之间的信息传递。在目前我们可以使用方法中PropTypes对props收集到的元素类型进行限制,它是需要通过引入插件实现的,否则会进行报错,限制为函数时的字段应该func,而不是function,defaultProps为标签的默认值,对于所收集的标签进行必要性、默认值、数据类型限制往往是很有必要的,props的值是只读的。
函数式组件可以使用props,其原因是props以参数的形式传递进入函数中,然后利用解构赋值将所收集到的标签属性解构赋值出来。props的使用方法比较简单,在此不进行过多的介绍。
2.2.3 refs
ref本质上是用于标签元素给自己打上标识的,便于在使用回调函数获取标签元素的某些属性时比较方便,组件的实例对象refs会以数组键值对的形式收集所有的ref,通过this.refs来进行相关的操作。在react中设置ref的方式有三种,官方推荐的还是第三种。
1、字符串形式的ref
字符串形式的ref目前并不推荐使用,而且过多的ref变量名容易重复使得代码维护变得困难。
//代码示例
class Demo extends ReactDom.Component{
showData=()=>{
//从refs收集到的ref种解构赋值获取input1
const {input1}=this.refs;
console.log(input1.value);
}
showData=()=>{
//从refs收集到的ref种解构赋值获取input2
const {input2}=this.refs;
alert(input2.value);
}
render(){
<div>
<input ref="input1" type="text" placeholder="点击按钮提示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示"/>
</div>
}
}
//渲染组件到页面
ReactDom.render(<Demo/>,document.getElementById("test"));
2、回调形式的ref
将当前所在的节点以参数的形式传入回调函数,回调形式的ref本质上是一个获取当前所在节点的函数,本结点所在的箭头函数以自定义的变量名赋值给组件实例对象,一般命名为currentNode。
//代码示例
class Demo extends ReactDom.Component{
showData=()=>{
//直接从this中解构赋值获取input2
const {input1}=this;
console.log(input1.value);
}
showData=()=>{
//直接从this中解构赋值获取input2
const {input2}=this;
alert(input2.value);
}
render(){
<div>
<input ref={c=>this.input1=c} type="text" placeholder="点击按钮提示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref={c=>this.input2=c} onBlur={this.showData2} type="text" placeholder="失去焦点提示"/>
</div>
}
}
//渲染组件到页面
ReactDom.render(<Demo/>,document.getElementById("test"));
3、使用createRef的API创建ref
这也是react官方所大力推崇的一种创建ref的方式,代码示例如下:
//代码示例
class Demo extends ReactDom.Component{
let myRef1=React.createRef();
let myRef2=React.createRef();
showData=()=>{
//直接从this中解构赋值获取input2
const {input1}=myRef1;
console.log(input1.value);
}
showData=()=>{
//直接从this中解构赋值获取input2
const {input2}=myRef2;
alert(input2.value);
}
render(){
<div>
<input ref=myRef1 type="text" placeholder="点击按钮提示数据"/>
<button onClick={this.showData}>点我提示左侧的数据</button>
<input ref=myRef2 onBlur={this.showData2} type="text" placeholder="失去焦点提示"/>
</div>
}
}
//渲染组件到页面
ReactDom.render(<Demo/>,document.getElementById("test"));
关于ref的总结:
1、字符串的形式是最简单的,refs会收集标签中所有的ref,此种方式一般要避免使用。
2、回调函数形式的ref,通过自定义的变量名获取回调函数传入的当前所在节点currentNode。
3、通过createRef创建的容器是专用的,也是最麻烦的,不过也是React最为推荐的一种方式。
特别备注:
在需要操作的节点为绑定事件的节点本身时,我们可以使用event.target来得到发生事件的dom元素,过度使用ref并不是一个好的行为。
三、总结归纳
本篇博客是react学习笔记的第一篇内容,简单的回顾一下。从JSX的基础概念到基础语法规则,函数式组件和类式组件的基础概念和特点介绍,组件中的三大属性state,props,refs的具体功能作用简介,以及中间穿插的关于原生JavaScript的事件绑定方式联系到react组件中的事件绑定方式,JavaScript的常见事件类型补充说明。
本专栏博客将持续更新记录本人学习react的笔记和感想,更新频率每周不少于2-3次。博客内容中如有错误之处,还望大家批评指出,一定改正。
回首向来萧瑟处,归去,也无风雨也无晴。