react基础教程---旧版

React基础教程(旧版):React教程旧版

【1】React知识点:React基础、全家桶、ReactNative

【2】讲解方式:从最基础搭建环境开始,按照知识点进行介绍,这样减少在工作中的出错频率,增加排查错误能力和解决效率。

 

大纲:

React-01课程介绍
React-02环境搭建和HelloWorld程序
React-03初识JSX语法
React-04进阶JSX语法
React-05t组件state成员
React-06Props和Render
React-07组件的生命周期
React-08组件小实例
React-09this.props.children
React-10组件的属性验证
React-11ref获取真实DOM节点
React-12表单bind复用
React-13表单name复用
React-14表单的可控组件
React-15表单的不可控组件

 

 

(1)React-01课程介绍

  

  特点:

1、虚拟DOM(Virtial DOM)
2、组件化(将项目按照功能进行横向划分)
3、React单向数据绑定,详见React的单向数据流与Vue的双向绑定.

  

 

(2)React-02环境搭建和HelloWorld程序

  

  链接:https://github.com/facebook/react/releases?after=16.1.0-beta

  下载对应代码库,然后在项目引入

  

注意:
    1、createClass写法是在V15版本之前的写法,V16开始摒弃了
    2、因为页面无法直接解析,所以需要通过babel解析。但这里的 babel主要依赖第三方包配合解析

  

  组件化与组件提取

  组件化概念:

首先要了解一点:在React里,整体就是一个组件化设计,增强可复用性和维护性

  对比之前的简单数据、XML嵌套数组,这里我们再次加大数据复杂度

  

   这里会看到JSX的render里的return方法使用了(),详解React之JSX里render中return方法添加括号()或者[].

   此时render的第一个参数优点累赘繁多,所以接下来举个案例,将其提取出去

  

  我们可以看到,setInterval定时器里调用函数时没有加函数执行符(),详解浅谈JS之常问问题:setInterval和setTimeout调用函数为什么不加小括号()???.

   接下来看下组件化,首先创建组件,React里创建组件有两种方法,如下所示

注意:
    这里因为React的相关依赖包版本问题,我们换用其他版本(V16之前的版本)去进行测试,将之前的依赖包一一替换掉
    <script src="http://static.runoob.com/assets/react/react-0.14.7/build/react.min.js"></script>
    <script src="http://static.runoob.com/assets/react/react-0.14.7/build/react-dom.min.js"></script>
    <script src="http://static.runoob.com/assets/react/browser.min.js"></script>

  

  1、第一种方法为React.createClass({})

  

   2、第二种方法为ES的class...extends...(ES6里Class 可以通过 extends 关键字实现继承)

  

   当然,构造器constructor主要用来来构造默认的属性和状态,这里可以省略

  

  如上所示我们将上个案例进行组件化抽离

  

 

   

 

(3)React-03初识JSX语法

  加入我们没有接触过JSX,那么之前的组件写法如下

  

第一行是创建组件
第二行是将组件进行转换渲染
缺点:纯JS操作,较为繁琐

  接下来介绍下JSX语法:

Javascript and XML

  之前的纯JS操作,虽然较为繁琐,但可以完成react所有操作。缺点较多:JS和标签混写在一起,缺乏模板的支持,写法很不友好。而JSX便可以很好解决这个问题

JSX语法需要Babel转换,所以在学习阶段,在客户端浏览器上进行测试时,需要结合browser.min.js或者browser.js进行转换预览。
注意:
    这种browser.min.js渲染编译方法效率较低,仅仅在开发学习阶段使用,正式工作开始一般不用

  babel的CDN链接:https://www.bootcdn.cn/babel-core/

  注意:不建议使用babel6.xxx以上版本,可能不再支持在线转换,所以使用5.xxx版本

  

  

对比JSX于之前JS的区别
    1、scrpit的type变为text/babel
    2、js创建元素,变为直接写html元素,较为直观方便

  拓展:live-server静态服务器启动预览

  

 

   

  

live-server优点:热更新

  详见文章web服务器live-server(热更新)的安装及使用.JSX支持表达式和动态传至,如下所示

  

  同时还支持三目运算符(三元表达式)、二目运算符(二元表达式)详见三元表达式(三目运算符)和二元表达式(二目运算符).、map遍历等... ...

注意:
    三元表達式和二元表达式都可以使用去取代if...else if ...else和if..else语法,但不支持if...else语法

  

   

(4)React-04进阶JSX语法

  JSX支持遍历语法,如下

  

   除了上面数组遍历方式,还有另一种,如下所示

  

  结合for循环(外部)

  

注意:

主流循环写法是 map,jsx里面不能用for循环,因为for循环不是表达式。
可以用Array::map方法,注意给返回的每一个组件设置一个唯一的key。详见React之JSX循环遍历方法对比.

 

 

(5)React-05t组件state成员

  组件的通俗理解:

可以看作一个带有props属性集合、state状态集合、并且构造出一个虚拟DOM结构的对象

  React最主要的创新就是将组件看成状态集合,用户界面的不同是根据状态进行渲染的,状态跟数据保持一致,类似于Vue,但Vue是数据驱动界面.

  React开发时主要也是针对state状态进行创建和更改操作

  

单向数据绑定:从这里可以看出React不同于Vue,为单向数据绑定,修改需要通过setState
注意:这里事件绑定必须用小驼峰法,因为JS对大小写敏感,HTML对大小写不敏感。

  

  

(6)React-06Props和Render

  首先了解下HTML的props,如下所示,input元素的属性便可以称之为input的props

 <input type="text">   这里type="text"便是props属性

  接下来看下React的props属性

  

 

  设计组件时需要考虑哪些是props属性集合,哪些是state状态集合

props:从父组件传递过来,例如类名、回调响应函数等
state:组件渲染时进行改变,或者生命周期操作的

  1、render是纯粹的

即render内部不建议放逻辑操作,state操作和方法应该放置到生命周期等等

  

 

 

 

(7)React-07组件的生命周期/钩子函数

  组件的生命周期也可以称之为钩子函数,主要包含挂载阶段、更新阶段、销毁阶段... ...

  

  案例如下:

  

  

  接下来进行渲染

  

  测试如下

  

 

  接下来点击按钮,更新state,如下所示

  

 

 

 

 

(8)React-08组件小实例

  该案例包含组件的属性props、状态state、生命周期等... ...,做一个字体闪动效果

  

 

   等待组件加载完毕,开始闪动,结合生命周期componentDidMount

  

 

   组件声明完毕,开始渲染DOM

  

 

   测试如下

  ...

1、什么时候使用state?
    需要在组件里进行更改变化的,最好使用state
2、什么时候用props?
    由父组件传递给字组件,不在字组件内部进行更改
3、为什么用生命周期?
  在React的组件里,render必须是纯粹的,不能有业务逻辑代码,尽量将业务逻辑代码放到生命周期钩子里.

 

 

(9)React-09组件的this.props.children组件内部所有子节点

  注意点:

this.props对象的属性与组件的属性一一对应,但有一个例外,就是this.props.children属性,它表示组件里的所有子节点

  

  案例如下

  

  

  结果如下:

  

 

  

(10)React-10组件的属性验证

  作用:对外界父组件传递过来的属性进行限定,例如希望name属性不可缺少且为字符串... ...,对此React引入了PropsTypes属性

  

  

  结果如下

  

注意:
    该警告只在开发模式下管用,生产模式下不再应用

  props默认值  

  

  如果父元素没有传递props,则会显示默认值。如果传递了则会覆盖默认值

  

 

 

 

 

(11)React-11ref获取真实DOM节点

  类似于Vue,React里同样应用了虚拟DOM技术。只有在组件挂在完毕后,才会渲染出真实DOM节点。

  案例:点击按钮时,将光标定位到输入框

  

 

   要求:点击按钮,输入框聚焦

  

  

 

  此时点击按钮,便可以实现输入框聚焦

  

 

(12)React-12表单bind复用

  

  效果如下:

  

  接下来进行state状态初始化

  

  接下来进行表单事件绑定,因为每次绑定语法差不多,所以这里我们借用bind实现语法抽离

  

  关于bind复用,在React表单里应用较为频繁。此时,可以在控制台进行监控

  

  

  接下来进行表单提交处理,如下所示

  

 

 

 

(13)React-13表单name复用

  上面案例是在表单利用bind进行复用,接下来利用name进行复用

  主要语法和之前类似,稍微修改即可,如下所示

  

 

  此时也不用bind绑定了

  

 

   完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- Load React. 
    Note: when deploying, replace "development.js" with "production.min.js"
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> 
    -->
</head>
<body>
    <div id="root"></div>
    <script src="./dist/react.js"></script>
    <script src="./dist/react-dom.js"></script>
    <script src="./dist/browser.js"></script>
    <script type="text/babel">
        // 定义组件
        var FormComponent = React.createClass({
            getInitialState(){return {name:'',location:'tj',confirm:false}},
            handleChange(e){
                let newState = {}
                newState[e.target.name] = e.target.name == "confirm" ? e.target.checked : e.target.value;
                this.setState(newState)
            },
            handleSubmit(e){
                e.preventDefault()
                let {name,location,confirm} = this.state
                var confirmValue = confirm == true ? '同意':'不同意'
                alert(name+location+confirm)
            },
            render(){
                let {name,location,confirm} = this.state
                return (
                    <form onSubmit={this.handleSubmit}>
                        <label htmlFor="name">姓名:</label>
                        <input 
                            id="name" type="text" name="name" 
                            onChange={this.handleChange} value={name}/><hr/>
                        <label>祖籍:</label>
                        <select 
                            name="location" value={location}
                            onChange={this.handleChange}>
                            <option value="sjz">石家庄</option>
                            <option value="bj">北京</option>
                            <option value="tj">天津</option>
                        </select><hr/>
                        <input 
                            id="confirm" type="checkbox" name="confirm" 
                            onChange={this.handleChange} checked={confirm}/>
                        <label htmlFor="confirm">您已经阅读相关条款并同意</label><hr/>
                        <button>提交</button>
                    </form>
                )
            }
        })
        // DOM渲染
        ReactDOM.render(<FormComponent />,document.getElementById("root"))
    </script>
</body>
</html>

实现name复用的关键

对比与bind复用,name复用要求每个元素必须加入name属性

 

 

 

 

(14)React-14表单的可控组件

  

 

  小结:input中的value绑定到state状态的React组件就是可控组件,否则是不可控组件.

  

  此时的input不可以编辑和删除

   

  接下来添加事件监听,便成了可控组件,可以编辑和删除input内容

  

 

  可控组件的两个特点:1、value绑定state状态集合;2、事件绑定,实时监控onChange事件.

 

 

 

(15)React-15表单的不可控组件

  一般日常开发都推荐使用可控组件,某些情况下也可以使用不可控组件

  

  如上所示,一个简单的input控件,只要不绑定value,便可以视为不可控组件

   接下来通过绑定方法获取该组件具体值,如下所示

  

 

   

  如果给不可控组件添加alue,则如下所示

  

 

   测试后会发现,由于React的渲染策略,这里的value无法再进行编辑删除等操作,那么不可控组件的默认值如何实现呢?此时需要用到defaultValue属性,如下所示

  

  此时便可以正常编辑

  

小结:
    不可控组件的默认值使用defaultValue属性实现,通过ref获取控件值

 

   

  

 

 

..

posted @ 2020-03-08 18:43  剑仙6  阅读(200)  评论(0编辑  收藏  举报
欢迎访问个人网站www.qingchun.在线