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的表单应用。如果有不对的地方还希望大家留言指出,谢谢!

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • ftp工具哪个好用_客户端游戏人气排行榜

    ftp工具哪个好用_客户端游戏人气排行榜序言:随着互联网的不断普及、发展,越来越多的人在使用FTP软件,它被广泛的应用于网页制作、网站更新、资源共享、数据传输等多个方面。“工欲善其事,必先利其器”,面对现在多如牛毛的各种FTP软件,我们到底选择哪一款才能更好的帮助我们呢?为此我们将针对当前比较流行的十款FTP客户端软件进行横向评测,通过下面的评测我们将会给出圆满的答案,希望能够给广大读者提供指引和帮助。导读:☆:

    2022年10月19日
  • android 自定义控件的两种做法[通俗易懂]

    android 自定义控件的两种做法

  • qlineedit_qt layoutstretch

    qlineedit_qt layoutstretch简述QLineEdit是一个单行文本输入框。QLineEdit允许用户输入和编辑单行纯文本,提供了很多有用的编辑功能,包括:撤消和重做、剪切和粘贴、以及拖放(见setDragEnabled())。通过改变输入框的echoMode(),同时也可以设置为一个“只写”字段,用于输入密码等。文本的长度可以被限制为maxLength(),可以使用一个validator()或inputMask()来任意限制文本

  • TiKV 性能参数调优[通俗易懂]

    TiKV 性能参数调优[通俗易懂]2019独角兽企业重金招聘Python工程师标准>>>…

  • 21位数激活码生成[最新免费获取]「建议收藏」

    (21位数激活码生成)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html…

  • Celer推出基于原子交换技术的跨链桥方案cBridge,今日主网上线

    Celer推出基于原子交换技术的跨链桥方案cBridge,今日主网上线据官方消息,CelercBridgev1.0版本今天正式主网上线。cBridge是一个支持高速低成本的跨链支付网络,用户可以立即使用cBridge在Ethereum、Arbitrum、BinanceSmartChain以及Polygon进行高速低成本跨链和跨层转账(cbridge.celer.network)。cBridge将会在短期内支持更多的layer2和layer1区块链的跨链和跨层转账。此外,任何人都将能够通过运行cBridge节点加入cBridge网络以提供跨链跨层流动性,同时通过收取手

发表回复

您的电子邮箱地址不会被公开。

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