React学习笔记01---jsx基础语法规则、函数式组件与类式组件

前言:最近跟着教程把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次。博客内容中如有错误之处,还望大家批评指出,一定改正。

回首向来萧瑟处,归去,也无风雨也无晴。

    

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值