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)
上一篇 2022年4月21日 下午3:20
下一篇 2022年4月21日 下午3:20


相关推荐

  • 我的世界java手机_我的世界java手机版

    我的世界java手机_我的世界java手机版我的世界java手机版是一款非常好玩的模拟经营游戏,游戏非常的自由,你几乎可以在游戏中干任何事,你可以自己建造一个世界,或是制作一个像素版的动漫人物,你还可以探索这个世界,寻找资源,你还可以和好友一起在这里进行对抗,你还在等什么,赶快来体验吧!我的世界java手机版游戏特色没有华丽的画面,没有什么游戏特效但是它最大的优势就是在于它的游戏性玩家在一个完全开放的世界,可以完全按照自己的想法建造我的世界…

    2022年7月8日
    22
  • 如何为pycharm配置解释器_python解释器加入pycharm

    如何为pycharm配置解释器_python解释器加入pycharm我们需要提前下载好python解释器解释器可以在Python解释器官网下载,这里我下载的是3.8.8版本的1、在我们安装好pycharm的时候,并不是直接可以用的,我们还需要配置解释器,不配置解释器的话,就会出现下面这种情况。此时,小伙伴们莫慌,只要我们配置好解释器就可以了。2、首先点击上图中“ConfigurePythonInterpreter”,之后Pycharm就会自动定位到“ProjectInterpreter”这个位置,如下图所示,该界面是Pycharm的设置窗口之一,专门用

    2022年8月26日
    11
  • 卷积与反卷积关系超详细说明及推导(反卷积又称转置卷积、分数步长卷积)

    卷积与反卷积关系超详细说明及推导(反卷积又称转置卷积、分数步长卷积)  以CNN为代表的卷积神经网络在图像的相关领域得到了较为长足的发展。在CNN中卷积实际分类两大类,一种是卷积,另一种是转置卷积(transposedconvolutional),或者称为分数步长卷积(fractionallystridedconvolutionallayers),亦或者是反卷积(deconvolution)。  虽然在一些文章中将反卷积与转置卷积认为是等价的…

    2022年6月21日
    31
  • 数据库之——sqlite下载及使用

    数据库之——sqlite下载及使用最近在研究 sqlite 的数据库 是因为项目需要存储大量数据 也需要查询 比起 txt 或者 excel xml 等方式 综合还是想用数据库保存 但是公司项目没有实施工程师 使用 sqlserver 怕客户不会安装 所以希望可以安装项目软件的时候自动安装 sql 数据库 查了很久的资料 还没有很好的方式解决 偶然发现 sqlite 不需要安装 很方便能部署到打包文件里面 如果你和我有同样的问题 可以使用 sqlite 的数

    2026年3月17日
    1
  • 彻底卸载Cursor编辑器

    彻底卸载Cursor编辑器

    2026年3月16日
    2
  • 写给大忙人看的 – Java中从MinIO服务器中下载文件(3)[通俗易懂]

    写给大忙人看的 – Java中从MinIO服务器中下载文件(3)[通俗易懂]前面两章介绍了MinIO文件服务器的环境搭建,以及在Java中上传文件至MinIO文件服务器中,现在,一起来看下如何从MinIO文件服务器中下载文件吧1、获取文件对象我们在MinIO工具类中,获取文件对象的方法,即获取文件的输入流对象/***获取文件**@parambucketNamebucket名称*@paramobjectName文件名称*@return二进制流*/@SneakyThrowspublicInputStreamge

    2022年7月12日
    276

发表回复

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

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