React—最简洁的技术学习(一)

React—最简洁的技术学习(一)React—最简洁的技术学习(一)

大家好,又见面了,我是你们的朋友全栈君。

摘要(本人感受)

此文章是本人在学习React过程中总结起来的一些小经验,因自己在网络上找到的React的教程很多都是一上来就是构建复杂的React环境,Webpack,ES2015等技术的使用,让其简洁的React变得复杂化。本文只为分享简洁的学习过程,让大家理解React,当然其中的不足之处,还望大家指出,谢谢。

React特点

1、虚拟DOM: React也是以数据驱动的,每次数据变化React都会扫码整个虚拟DOM树,自动计算与上次虚拟DOM的差异变化,然后针对需要变化的部分进行实际的浏览器DOM更新。

2、组件化: React可以从功能角度横向划分,将UI分解成不同组件,各组件都独立封装,整个UI是由一个个小组件构成的一个大组件,每个组件只关系自身的逻辑,彼此独立。

3、单项数据流:React设计者认为数据双向绑定虽然便捷,但在复杂场景下副作用也是很明显,所以React更倾向于单向的数据流动-从父节点传递到子节点。

理解了React的特点之后,开始学习React的基本组件。

一、 Hello World开始


刚开始学习React,暂时不考虑工程化的问题,React的运行环境十分简单,只需要在HTML文件中引入2个js(react.js 和 react-dom.js)文件即可开始工作。

react.js:实现React核心逻辑,但是与具体的渲染引擎无关,从而可以跨平台公用。如果需要迁移到React Native,这部分逻辑是不需要改变的。

react-dom.js:包含了具体的DOM渲染更新逻辑,以及服务端渲染的逻辑,这部分就是与浏览器相关了。

作为程序员,学习的第一步就是 Hello World的开始。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="./react.js"></script>
    <script src="./react-dom.js"></script>
  </head>
  <body>
      <div id="container"></div>
      <script>
            //创建Hello组件
            var HelloComponent =React.createClass({
                render:function(){
                    return React.createElement('h1',null,'Hello world');
                }
            });
            
            ReactDOM.render(
                React.createElement(HelloComponent,null),
                document.getElementById('container')
            )
      </script>
  </body>
</html>
复制代码

在上面这段代码中 React.createClass的作用是注册一个组件类HelloComponent,这个组件类只包含了一个render函数,这个函数通过调用React.createElement实现了以下HTML的内容:

这是React在创建组件时使用的基本语法,在后面我们学习了JSX的语法后,这种写法就不适用了,所以目前先记住这种使用。

二、初识JSX语法


JSX也就是JavaScript XML,它是使用XML标记来创建虚拟DOM和声明组件,在上节介绍中,我们发些在书写方面有些麻烦,影响开发效率问题,比如会出现JavaScript代码与标签混写一起、缺乏一些模板的支持,但是使用JSX,则可以有效的解决这些问题。

加入JSX语法支持

如果我们在代码书写中需要使用JSX的语法,可以使用Babel来进行转换,个人是直接引入Babel的核心文件browser.min.js。如果需要使用,可以去网上提供的静态资源库引用www.bootcdn.cn/ ,可以自行搜索下载哦。

使用JSX语法书写Hello World

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
  </head>
  <body>
      <div id="container"></div>
      
      <script type="text/babel">
       var HelloComponent =React.createClass({
            render:function(){
                return <h1>Hello World</h1>
            }
        });
        ReactDOM.render(
            <HelloComponent />,
            document.getElementById('container')
        )
      </script>
      
  </body>
</html>
复制代码

通过这种写法可以发现JSX的好处:

  • 可以使用熟悉的语法来仿照HTML来定义虚拟DOM;
  • 与JavaScript之间等价转换,程序代码更加直观;
  • JSX还可以防注入攻击。React DOM 在渲染之前默认会过滤所有传入的值。它可以确保你的应用不会被注入攻击。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(跨站脚本) 攻击。

Vue中可以使用{
{ }}表达式的写法,React中我们只需要一个{ }表达式即可支持。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
  </head>
  <body>
      <div id="container"></div>
      
          <script type="text/babel">
           var HelloComponent =React.createClass({
                render:function(){
                    //三元表达式
                    return <h1>Hello {
   
   true?'World2':''}</h1>
                }
            });
            ReactDOM.render(
                <HelloComponent />,
                document.getElementById('container')
            )
          </script>
      
  </body>
</html>
复制代码

需要注意的是表达式中不支持if…else这样的语句,但是支持三元运算符和二元运算符。

三、进阶JSX语法


上一节中了解到基本的JSX语法,这节深入了解一下,这边会给大家提醒一些小坑,帮助大家更好的节约学习时间。

JSX数组遍历 学习过vue的小伙伴们一定知道,在vue中通过v-for的方式去遍历出数组中的内容,而在React中用JSX语法中用表达式的方式去进行数组的遍历。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
  </head>
  <body>
      <div id="container"></div>
      <script type="text/babel">
      
        let names = ['React','Vue','Angular'];
        
        var NameComponent = React.createClass({
            render:function(){
                //  此处有坑哦
                return <div>
                        {
                            names.map(function(name){
                                return <div key={name}>Hello,{name}!</div>
                            })
                        }
                    </div>
            }
        });

        ReactDOM.render(
            <NameComponent />,
            document.getElementById('container')
        )
      </script>
  </body>
</html>
复制代码

在我们注重格式化书写的时候,可能会在render函数中的return后进行断开书写,这样显得格式化更好些:

如果这样书写,你将会看到:

控制台报错了,一脸懵!!!

在React中,render函数中的return后必须接上返回内容,否则会认为无值返回,控制台会报错提示。在其他的return中若没接上返回内容,虽然不会报错,但是会以无值形式返回,导致渲染不出后面的数据。

在此你可以在return后面加上一个(),这样你就可以进行格式化书写了:

我们发现在数组遍历中我们都需要加上遍历的key,无论是vue或者是React中都需要使用key,如果没有key虽然会出来效果,但是控制台会报错。key的作用是生成虚拟DOM时,需要使用key来进行标记,DOM更新时进行比较。

    {
        names.map(function(name){
            return <div key={name}>Hello,{name}!</div>
        })
    }
复制代码

如果无key的添加:

数组中的JSX

JSX允许在模板中插入JavaScript变量,如果这个变量是一个数组,就会展开这个数组的所有成员。

let arr=[
    <h1 key="1">我是React!</h1>,
    <h2 key="2">我是Vue!</h2>
];
ReactDOM.render(
    <div>{arr}</div>, 
    document.getElementById('container') 
)
复制代码

四、Props和State的学习


React组件可以把它看作带有props属性集合和state状态集合并且构造出一个虚拟DOM结构的对象。

Props

props是组件中固有属性的集合,其数据由外部传入,一般在整个组件的生命周期中都是只读的。属性的初始值通常由React.createElement函数或者JSX中标签的属性值进行传递,并合并到组件实例对象的this.props中。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Props</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    <style>
    </style>
  </head>
  <body>
      <div id="container"></div>
      <script type="text/babel">
        
        let HelloBox = React.createClass({
            render:function(){
                return (<div>{
   
   'Hello '+this.props.name}</div>)
            }
        })

        ReactDOM.render(
            <HelloBox name='React' />,
            document.getElementById('container')
        )

      </script>
  </body>
</html>
复制代码

this.props后面携带的值需要与组件传递的属性值保持一致。

State

组件总是需要和用户互动的。React的一大创新,就是将界面组件看成一个状态机,用户界面拥有不同状态并根据状态进行渲染输出,用户界面和数据始终保持一致。开发者的主要工作就是定义state,并根据不同的state渲染对应的用户界面。

举个实例让大家感受一下:

这个例子包含一个input框和一个button,通过点击button来改变input的disable状态。
复制代码
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Props和State</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.mim.js"></script>
    <style>
        input:disabled{
            border: 1px solid red;
        }
        button{
            cursor: pointer
        }
    </style>
  </head>
  <body>
      <div id="container"></div>
      <script type="text/babel">

        var TextBoxComponent = React.createClass({
            
            //初始化原始数据 ,与Vue中的data类似
            getInitialState:function(){
                return {
                    enable:true
                }
            },

            render:function(){
                return(
                    <p>
                        //通过this.state去获取enable的初始化值
                        <input type="text" disabled={this.state.enable} /> 
                        <button>改变状态</button>
                    </p>

                )
            }
        })

        ReactDOM.render(
            <TextBoxComponent />,
            document.getElementById('container')
        )

      </script>
  </body>
</html>
复制代码

目前暂时还不能点击button去改变disable的状态,在React单向数据流的条件下,我们无法向Vue那样直接去操作改变disable的状态,需要去借助setState函数去处理。

setState函数

通知React组件数据发生变化的方法是调用成员函数setState(data,callback)。这个函数会合并data到this.state,并重新渲染组件。渲染完成后,调用可选的callback回调。(大部分情况下不需要调用回调,因为React会负责把界面更新到最新状态)

因此我们给button加上我们的点击事件,通过setState去改变disable的值。

在上面的代码中我们需要注意几点:

  • getInitialState函数必须有返回值,可以是null,false,一个对象。
  • 访问state数据的方法是”this.state.属性名”。
  • 变量用{ }包裹,不需要再加双引号。

props与state的区别

props不能被其所在的组件修改,从父组件传递进来的属性不会在组件内部更改;

state只能在所在组件内部更改,或在外部调用setState函数对状态进行间接修改。

五、React生命周期


一个组件完整的生命周期包含实例化阶段、活动阶段、销毁阶段三个阶段。每个阶段又由相应的方法管理。

这些过程中涉及三个主要的动作术语:

  • mounting: 表示正在挂载虚拟DOM到真实DOM;
  • updating: 表示正在被重新渲染;
  • unmounting:表示正在将虚拟DOM移除真实DOM。

在每个动作术语中提供了一些函数供我们使用:

  • componentWillMount():表示将要或正挂载过程中;
  • componentDidMount():表示已经挂载完成了;
  • componentWillUpdate(object nextProps, object nextState):表示将要或正在重新渲染;
  • componentDidUpdate(object prevProps, object prevState):表示重新渲染完成了;
  • componentWillUnmount():表示虚拟DOM卸载了。

通过一个简单的实例,来看React组件的生命周期。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>生命周期</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    <style>
    </style>
  </head>
  <body>
      <div id="container"></div>
      <script type="text/babel">

      var AddCount = React.createClass({
      
          //数据初始化
          getInitialState:function() {
              console.log('1-getInitialState')
              return {
                  count:1
              }
          },
          
          componentWillMount() {
              console.log('2-componentWillMount')
          },

          componentDidMount(){
              console.log('3-componentDidMount')
          },

          componentWillUpdate(){
              console.log('4-componentWillUpddate')
          },
          
          componentDidUpdate(){
              console.log('5-componentDidUpdate')
          },

          handleClick:function(event){
              this.setState({
                  count:this.state.count+1
              })
          },
          
          render:function(){
              return(
                  <p>
                    {this.state.count} <br/>
                    <button onClick={this.handleClick}>点击加一</button>
                  </p>
              )
          }
      })


      ReactDOM.render(
          <AddCount />,
          document.getElementById('container')
      )
      </script>
  </body>
</html>
复制代码

点击之后:

六、获取真实DOM节点


React中的DOM也是虚拟DOM(virtual DOM),这点跟Vue非常类似。只有当它插入文档以后,才会变成真实的DOM。React也是在虚拟DOM发生变化时,进行比对后,只渲染变化的部分,它是React极高性能的主要原因之一。

但是有时候我们需要从组件中获取真实的DOM节点,来进行业务逻辑的编写,React为我们提供了ref属性。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>ref</title>
    <script src="./common/react.js"></script>
    <script src="./common/react-dom.js"></script>
    <script src="https://cdn.bootcss.com/babel-core/5.8.38/browser.mim.js"></script>
    <style>
    </style>
  </head>
  <body>
      <div id="container"></div>
      <script type="text/babel">
        var MyComponent = React.createClass({

            handleClick:function(event){
                //通过this.refs去获取,这点和Vue相似
                this.refs.myTitleInput.focus();
            },

            render:function() {
                return(
                    <div>
                        <input type="text" ref="myTitleInput" /> <br/>
                        <input type="button" value="Focus on input" onClick={this.handleClick} />
                    </div>
                )
            }
        })

        ReactDOM.render(
            <MyComponent/>,
            document.getElementById('container')
        )
      </script>
  </body>
</html>
复制代码

通过这些知识点的学习,可以初步的了解到React的基本知识。下一章将分享React的表单应用。如果有不对的地方还希望大家留言指出,谢谢!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107016.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • PhpStorm激活码2024.3.3版本最新教程,永久有效激活码,亲测可用,记得收藏

    PhpStorm激活码2024.3.3版本最新教程,永久有效激活码,亲测可用,记得收藏PhpStorm 激活码教程永久有效 2024 3 3 激活码教程 Windows 版永久激活 持续更新 Idea 激活码 2024 3 3 成功激活

    2025年5月23日
    1
  • 控制台打印图形_前端控制台打印

    控制台打印图形_前端控制台打印问题描述一、在控制台输出以星号打印的三角形思路:在外部使用循环语句执行5次每次打印1行,每行的内容分别为空格和星号,每行空格缩进的数量为5减去所在行数,星号的数量是所在行数的2倍减1。在内部使用循环语句首先打印空格,然后打印星号”*”,对应的打印次数用循环次数控制,打印星号之后就可以换行。publicstaticvoidmain(String[]args){ //打印图形, intn=5;//表示要打印几行 for(inti=1;i<=n;i++){//i表示每行

    2022年10月20日
    0
  • 傅里叶分析之掐死教程(完整版)

    傅里叶分析之掐死教程(完整版)

    2021年11月21日
    44
  • CheckListBox的使用方法

    CheckListBox的使用方法checklistbox控件 1.添加项 checkedListBox1.Items.Add(“蓝色”); checkedListBox1.Items.Add(“红色”); checkedListBox1.Items.Add(“黄色”);   2.判断第i项是否选中,选中为true,否则为false if(checkedListBox1.G

    2022年6月26日
    48
  • outputstream的子类_java里input

    outputstream的子类_java里inputJavaInputStream类在本教程中,我们将通过一个示例来学习JavaInputStream类及其方法。java.io包的InputStream类是一个抽象超类,它表示字节的输入流。由于InputStream是抽象类,因此它本身没有用。但是,其子类可用于读取数据。InputStream的子类为了使用的InputStream功能,我们可以使用其子类。它的子类有:在下一个教程中,我们将学习…

    2022年9月17日
    0
  • JMeter下载安装以及使用教程

    JMeter下载安装以及使用教程JMeter下载1、下载地址:https://jmeter.apache.org/download_jmeter.cgi2、下载后无需安装,解压后即可使用。解压后目录如下:3、打开JMeter中bin目录下面的jmeter.bat双击即可打开JMeter了,打开的时候会有两个窗口,Jmeter的命令窗口和Jmeter的图形操作界面,不要关闭命令窗口,打开界面如下:4、打开jmeter软件,发现显示的为英文,更改为中文步骤如下:点击菜单栏【Options】按钮然后依次单击【Cho

    2025年6月16日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号