锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

react_T_v18

时间:2023-10-18 22:37:00 ad7819yrz集成电路ic

React

一、React的简介

1、介绍

  1. React 是一个用于构建用户界面的 JAVASCRIPT 库。

  2. React主要用于施工UI,很多人认为 React 是 MVC 中的 V(视图)。

  3. React 起源于 Facebook 内部项目用于架设 Instagram 并于网站 2013 年 5 月开源。

  4. React 性能高,代码逻辑很简单,越来越多的人开始关注和使用它

2、特点

1). 高效 ?React通过对DOM最大限度地减少和模拟DOM的交互。

2). 灵活 ?React可以与已知的库或框架很好地配合。

3). JSX ? JSX 是 JavaScript 语法的扩展。React 不一定使用开发 JSX ,但是我们建议使用它。

4). 组件 ? 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

单向响应数据流 ? React 实现了单向响应数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

3、框架对比

与其他框架的共同点是使用虚拟dom,和数据驱动

angularJs reactJs vueJs
控制器 - -
过滤器 -
指令 -
模板语法 -
服务 - -
组件 -
jsx - 2.0之后加入

二、环境建设

1、引入文件的方式(CDN)

1、React.js:

React核心库,分析组件,识别jsx

https://cdn.staticfile.org/react/16.4.0/umd/react.development.js

2、reactDom.js:

处理有dom相关的操作

https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js

3、Babel.js

Babel 可以将 ES6 代码转为 ES5 这样,我们目前就不能支持代码了 ES6 执行在浏览器上 React 代码。Babel 内嵌了对 JSX 支持 Babel 和 babel-sublime 包(package)一起使用可以将源代码的语法渲染提升到一个新的水平

https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js

2.官方脚手架(模块化)

安装 create-react-app

yarn global add create-react-app | npm install create-react-app -g 

创建 react项目

create-react-app 目录 | npx create-react-app 目录 | npm init react-app 目录 yarn eject   解构所有配置文件 可选 yarn start |  npm start    开发 yarn build |  npm run build  打包  //调试 需要安装给chrome浏览器插件 react-dev-tools 

环境解析

  • react: 核心包,分析组件,识别jsx
  • react-dom: 编译 -> 浏览器
  • react-scrpts: react项目环境配置
  • manifest.json 当生成一个网页的桌面快速方式时,图标和文本将显示该文件中的内容
  • registerServiceWorker.js支持离线访问,因此与原生一起使用app体验非常接近,只包装生成在线版本react项目时,registerServiceWorker.js有效。必须使用服务器。https协议
  • 对Internet Explorer 需要9、10和11的支持polyfill。

第三方脚手架

yeomen/dva/umi

第一个React程序

    HelloReact!          

注意:

1、script标签的type取值为:text/babel

2、在script标签里写的html代码,不用双引号或者单引号,这种写法是下面要讲解的jsx。

总结:一个react的程序,就是把JSX通过ReactDOM.render()函数渲染到网页上。

另外,React的代码也可以单独写在一个文件里,扩展名为js,或者jsx。引入时,记住type=“text/babel”

JSX

1、JSX的介绍

​ 什么是JSX:JSX=javascript xml,就是Javascript和XML结合的一种格式。是 JavaScript 的语法扩展,换句话说:只要你把HTML代码写在JS里,那就是JSX

​ 在实际开发中,JSX 在产品****打包阶段****都已经编译成纯 JavaScript,不会带来任何副作用,反而会让代码更加直观并易于维护。官方定义是:类 XML 语法的 ECMAScript 扩展。

2、特点:

​ JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。

​ 它是类型安全的,在编译过程中就能发现错误。

​ 使用 JSX 编写模板更加简单快速。

3、JSX的语法

​ JSX就是把html代码写在javascript中,那么,写在javascript中有啥要求(与原来在html中的区别),这就是jsx语法要说的内容。

​ 示例:

var msg="哥们!"

const element = <h1>Hello, world { 
        msg}</h1>     没有双引号,不是字符串

const List = () => (<ul><li >list item</li><li>list item</li><li>list item</li></ul>  

  );   

XML基本语法

  • 只能有一个根标签,养成外面加上圆括号的习惯。

  • 标签要闭合(单边标签得有斜杠)

元素类型

  • 小写首字母对应 HTML的标签,组件名首字母大写。

  • 注释使用 / * 内容 */ html标签内注释{/* 最外层有花括号*/}

元素属性

  • 内联样式的style:

    style属性不能直接按照html的写法写。应该用 JavaScript的写法(json对象)

    样式名以驼峰命名法表示, 如font-size需写成fontSize。默认像素单位是 px(px不用写)

    	let _style = { backgroundColor:"red" };
    	
    	ReactDOM.render(
    	    

    Hello, world!

    , document.getElementById('box') );
  • 外部样式的class:HTML中曾经的 class 属性改为 className(因为class是js的关键字),外部样式时使用

    	ReactDOM.render(
    	    

    Hello, world!

    , document.getElementById('box') );
  • for 属性改为 htmlFor(因为for是js的关键字)。(for属性在html标签中是扩充单选框|复选框的选择范围)

  • 事件名用驼峰命名法。HTML是全小写(onclick),JSX中是驼峰(onClick)

javascript表达式

  • 使用单花括号

    react里没有vue中的指令,在JSX的任何地方需要javascript的变量,表达式等等,只需要套上 单花括号就行。

    const element = 

    Hello, {120+130}!

    const element =

    Hello, {getName("张三疯")}!

    注意:单花括号里只能写表达式,不能写语句(如:if,for)

总结:

​ 对比原生,JSX相当于把原生里的html和javascript代码混写在一起,

​ vue中有很多的指令,react中只需要使用单花括号就行。

ReactDOM.render()函数

​ ReactDOM.render 是 React 的最基本方法。用于将JSX写的模板(经过模板渲染(把javascript的结果替换单花括号里的内容))转为 HTML 语言,并渲染到指定的HTML标签里。

​ ReactDOM.render( JSX写的html模板,dom容器对象);

总结:一个react的程序,就是把JSX通过ReactDOM.render()函数渲染到网页上。

​ 程序员完成的是JSX的编写。

条件渲染

var sex='女';
if(sex=='男'){
	var sexJSX=

我是男的

; }else{ var sexJSX=

我是女的

; } ReactDOM.render(
    {sexJSX}
, document.getElementById('box') );

注意:if语句不要写在单花括号里。

列表渲染

1)、渲染数组:

//数组里存放jsx
var arr=[
    
  • 张三疯
  • ,
  • 张四疯
  • ,
  • 张五疯
  • ] const show = ()=> (
      {arr}
    ) ReactDOM.render(show(),document.getElementById("box"));

    2)使用Javascript的map()或者普通for循环进行列表的渲染

    //普通for循环
    
    let arr = ["铅笔","油笔","钢笔","毛笔"];
    var arr2 =[];
    for(let i in arr){
    	arr2.push(
  • {arr[i]}
  • ); } const show = ()=> (
      {arr2}
    ) ReactDOM.render(show(),document.getElementById("box")); //map const goods = ['铅笔','钢笔']; const goodsJSX = goods.map(function(val,index){ return
  • {val}
  • }); ReactDOM.render( //以下相当于react里的模板,不能出现js的语句,可以有表达式
      {goodsJSX}
    , document.getElementById('box') );

    组件

    react中定义组件有三种写法:函数方式,ES5的写法,ES6(类)的写法

    函数方式的组件

    函数的返回值是JSX就行。即就是:如果一个函数的返回值是JSX,那么就可以当标签的方式使用。

    	// 定义组件,组件名首字母大写(大驼峰)
    	function MyCom(){
    		const msg="hello";
    		return (
    			
    • {msg}:三国演义
    • {msg}:红楼梦
    ) } ReactDOM.render( , //使用组件 document.getElementById('box') );

    ES5的写法:

    React.CreateClass()函数(React16后,已经被废弃了)

    var MyCom = React.createClass({  
      render:function(){ //vue中也有render函数,是完成模板的代码
        return (
          

    Hello, world!

    ); } });

    ES6类定义组件:

    定义一个类,继承自 React.Component,并且,在该类里,必须有个render()函数,render函数返回一个JSX代码

    换句话说:一个普通的ES6的类,继承自React.Component,有一个render()函数,并且render()函数返回一个JSX,那么就是组件。

    	// 定义组件
    class MyCom extends  React.Component{
    	constructor(props){ //props:是外部传入的数据,相当于vue中的props
    		super(props);
    		// state是内部的数据,相当于vue中的date
    		this.state={
    			name:"田哥"
    		}
    	}
    
    	render(){
    		const msg="hello";
    		return (
    			
    • {this.state.name}:三国演义
    • {msg}:红楼梦
    ) } }

    多个组件

    	// 标题
    	function MyTitle(){
    		return (
    			

    商品列表

    ) } // 详情 function MyDetail(){ return (
    • 铅笔
    • 钢笔
    ) } ReactDOM.render(

    , document.getElementById('box') );

    props

    props 是组件对外的接口。接收外部传入的数据。是组件的属性(等同于html标签的属性)。
    注意:Props对于使用它的组件内部来说,是只读的一旦赋值不能修改

    外部传值:

    <组件名 属性名1=值1 属性名2=值2 .. />
    

    属性值=“静态值”

    属性值={js数据}

    组件内部使用:

    1)、函数组件:

    {props.属性名}
    

    示例:

    function MyPerson(props){
    	return (
    		

    {props.name}

    {props.sex}

    ) } ReactDOM.render( , document.getElementById('box') );

    2)、类组件:

    {this.props.属性名}
    

    示例:

    class MyPerson extends React.Component{
    	
    	render(){
    		return (
    			

    {this.props.name}

    {this.props.sex}

    ) } } ReactDOM.render( , document.getElementById('box') );

    **补充:**如果传递数据多的话,可以使用对象,但是必须使用扩展运算符(…)

    扩展运算符: https://blog.csdn.net/jiang7701037/article/details/103192777

    class MyPerson extends React.Component{ 
            
    	// constructor(props){ 
            
    	// super(props); 
    	// }
    	render(){ 
            
    		return (
    			<div>
    				<p>{ 
            this.props.name}</p>
    				<p>{ 
            this.props.sex}</p>
    			</div>
    		)
    	}
    }
    
    let person={ 
            
    	name:"张三疯",
    	sex:"男"
    }
    
    ReactDOM.render(
    	<MyPerson { 
            ...person}/>,
    	document.getElementById('box')
    );
    

    props的默认值

    1)、用 ||

    function MyPerson(props){
    	let sex1 = props.sex || "女";
    	return (
    		

    性别:{sex1}

    ) } ReactDOM.render( , document.getElementById('box') );

    2)、defaultProps

    格式:
    
    //1)、函数式组件和类组件都可以:
    
    组件名.defaultProps={
        属性名: 默认值
    }
    
    //2)、若为类组件,也可以在类的内部使用static修饰。
    
    static defaultProps={
        属性名: 默认值
    }
    
    
    示例:
    function MyPerson(props){
    	let sex1 = props.sex || "女";
    	return (
    		

    姓名:{props.name}

    性别:{sex1}

    ) } MyPerson.defaultProps={ name:"无名氏" } ReactDOM.render( , document.getElementById('box') );

    props的类型检查:

    注意:react15.5后,React.propTypes已经移入到另外一个库里,请使用prop-types。

    https://cdn.staticfile.org/prop-types/15.6.1/prop-types.js

    
    //类型约定:
    组件名.propTypes={	
        属性名1:PropTypes.类型名,
        属性名2:PropTypes.类型名
        //必传参数
    	属性名: PropsTypes.类型名.isRequired
    }
    
    

    类型名的可以取值为:

    PropTypes.array,
    PropTypes.bool,
    PropTypes.func,
    PropTypes.number,
    PropTypes.object,
    PropTypes.string,
    PropTypes.symbol,

    如:

    function MyPerson(props){
    	return (
    		

    年龄:{props.age}

    ) } MyPerson.propTypes={ //注意大小写 age:PropTypes.number.isRequired } ReactDOM.render( , document.getElementById('box') );

    state状态机(类组件)

    state 是状态,状态就是数据,state表示组件的内部数据(相当于vue组件中的data)。而props是外部传入组件的数据,类组件可以直接使用state,但是函数式组件就得用hooks(useState)

    定义并初始值

    class App extends React.Component {
      constructor(props){   
          super(props);  
          //在react中,如果希望状态的变化会引起其它数据或者界面的变化,那么,把数据定义在state里。对应着vue中的data。
          this.state={
        	  //设置状态的初始值
           	  属性名:属性值
          }
      }
    }
    

    读取状态

    this.state.属性名
    

    修改状态

    必须调用setState()函数,不要直接赋值,而且,setState()函数是异步的

    ​ 这是因为react框架的响应式原理和vue框架的响应式原理根本就不一样。

    ​ 1)、react框架的setState方法内部会调用render函数,这样就实现了重新渲染

    ​ 2)、vue框架用的是数据劫持。

    **1、修改状态时,**必须要调用setState。因为,只要调用了setState函数,那就会调用了render()。如果直接赋值,不会把数据响应式地渲染到DOM上。(即:没有调render()函数)

    class Book extends React.Component{        
    
            constructor(props){
                super(props);
                this.state = {
                    copyright:"版权归2011"
                }
    
                // 千万不能这么干,因为,数据修改后,不会响应式的呈现页面上(不会再次渲染DOM)
                // this.copyright="版权归2011";
    
                // 下面这句话,可以先不管
                this.changeVal = this.changeVal.bind(this);
            }
    
            changeVal(){
                // this.copyright = "哈哈哈";
                // console.log("this.copyright ",this.copyright);
    
                // 这不行,这个不会把数据响应式地渲染到DOM上。(即:没有调render()函数)
                // this.state.copyright = "哈哈哈";
    
                // 这 行,因为,只要调用了setState函数,那就会调用了render();
                this.setState({
                    copyright:"哈哈哈"
                });
            }
    
            render=()=>{
                console.log("render");
                return (
                    
    • 书名:{this.props.name}
    • 书龄:{this.props.age}
    • {this.state.copyright}
    • {this.copyright}
    ) } } Book.propTypes = { "name":PropTypes.string.isRequired, "age":PropTypes.number } const jsx =
    ReactDOM.render(jsx,document.getElementById("box"));
    //浅合并state
    this.setState({ 
            
    	属性名:属性值
    })
    
    示例代码:
    //1、假设定义的状态是:
    this.state = { 
            
        person:{ 
            
            name:"魏鹏",
            sex:"男"
        }
    }
    //2、如果修改时,使用下面的方式,肯定不行。因为,是浅合并,不会进入到下一级的属性进行对比
    this.setState({ 
            
        person:{ 
            
            name:"鹏鹏"
        }
    })
    
    

    vue和react在响应式上的区别:

    1、vue:背后使用了数据劫持和观察者模式

    2、react,修改数据时,调用setState,setState内部调用了render。

    2、setState()函数是异步的

    //改变状态前想做一些事情:
    this.setState((prevState,prevProps)=>{
      //一般是用于在setState之前做一些操作,this.state==prevState==修改之前的state 
        
       return {
        sname:value
      }
    }) 
    
    //改变状态后想做一些事情(如:使用新值):
    this.setState({
      属性名:属性值
    }, () => {
        
      //一般是用于在setState之后做一些操作。
      //this.state == 修改之后的state
        
    })
    
    
    //改变状态前后都想做一些事情:
    this.setState((prevState)=>{
        // prevState:是旧值
        console.log("prevState",prevState)
        return {
            age:15
        }
    },()=>{
        // this.state:就是新值。
        console.log(this.state.age);
    });
    
     class Book extends React.Component { 
            
    
            constructor() { 
            
                super();
                this.msg = "hi";
                this.state = { 
            
                    name: "三国演义",
                    author: "李茂军02"
                }
                this.changeVal = this.changeVal.bind(this);
            }
    
            changeVal() { 
            
    
                // setState函数是异步的
                // this.setState({ 
            
                // name:"ddd"
                // });
    			//console.log("this.state.name", this.state.name);//三国演义
                
                // 在修改状态之前做事情
                // this.setState((prevState)=>{ 
            
                // console.log("prevState",prevState); //三国演义 
                // console.log("this.state",this.state);//三国演义
                // return { 
            
                // name:"ddd"
                // }
                // });
    
                // 在修改之后做一些事情
    
                this.setState({ 
            
                    name: "ddd"
                }, () => { 
            
                    console.log("this.state.name", this.state.name);//ddd
                    console.log(document.getElementById("pId").innerHTML);//ddd
                });
    
            }
    
            render() { 
            
                console.log("render");
                return (
                    <div>
                        <p>{ 
            this.msg}</p>
                        <p id="pId">书名:{ 
            this.state.name}</p>
                        <p>作者:{ 
            this.state.author}</p>
                        <p>价格:{ 
            this.props.price}</p>
                        <input type="button" value="修改" onClick={ 
            this.changeVal} />
                    </div>
                )
            }
        }
    
        const h = (<div>
            <h1>hello 我是react</h1>
            <div>
                <Book author="李茂军" price="9.9" />
            </div>
        </div>);
    
        ReactDOM.render(
            h,
            document.getElementById("box")
        );
    
    

    注意:

    1、 直接修改state属性的值不会重新渲染组件 ,如:this.state.msg=“hello”; //亲,千万不要这么干

    补充:

    给引用类型的某个属性赋值

    class Book extends React.Component{    
    
            constructor(props){
                super(props);
                this.state = {
                    book:{
                        name:"做一个有钱的人",
                        age:22
                    }
                }
                this.changeVal = this.changeVal.bind(this);
            }
    
            changeVal(){
                // 这是不行的
                // this.setState({
                //     "book.name":"做一个有意义的人"
                // });
    
                // 得这样做(浪费了空间):就得这么写
                let b = {
                    ...this.state.book,
                    name:"做一个有意义的人"
                };
                this.setState({
                    book:b
                });
                
                //或者这样做(节约了空间):这样不推荐,因为,这样破坏了setState的异步
                let b = this.state.book;
                b.name = "大学";
                this.setState({
                    book:b
                });
    
            }
    
            render=()=>{
                return (
                    
    • {this.state.book.age}
    • {this.state.book.name}
    ) } }

    示例代码:

    1)、基本示例:

    class MyPerson extends React.Component{
    	constructor(props){
    		super(props);
    		this.state={
    			age:12
    		}
    		this.changeAge = this.changeAge.bind(this);
    	}
    
    	changeAge(){
    		this.setState({
    			age:this.state.age+1
    		});
    	}
    
    	render(){
    		return (
    			

    年龄:{this.state.age}

    ); } }

    2)、setState是异步的示例:

    
    class MyPerson extends React.Component{
    	constructor(props){
    		super(props);
    		this.state={
    			age:12,
    			isAdult:"未成年"
    		}
    		this.changeAge = this.changeAge.bind(this);
    	}
    	
    	/*
    	这种写法达不到效果:
    	changeAge(){
    		this.setState({
    			age:this.state.age+1
    		});
    		// setState是异步的,所以,以下的打印不是最新的值
    		console.log(this.state.age);
    		// setState是异步的,所以,以下的判断达不到效果
    		if(this.state.age>=18){
    			this.setState({
    				isAdult:"已成年"
    			});
    		}
    	}
    	*/
    	
    	changeAge(){
    		this.setState({
    			age:this.state.age+1
    		},()=>{
    			console.log(this.state.age);
    			if(this.state.age>=18){
    				this.setState({
    					isAdult:"已成年"
    				});
    			}
    		});
    	}
    
    	render(){
    		return (
    			

    年龄:{this.state.age}

    年龄:{this.state.isAdult}

    ); } }

    无状态组件

    ​ 无状态组件就是组件内部没有(不需要)state,无状态组件也可以理解为展示组件,仅做展示用,可以根据外部传来的props来渲染模板的内容,内部没有数据。相当于木偶(没脑子)。你说显示啥,咱就显示啥。

    var MyFooter = (props) => (
        
    {props.xxx}
    );

    仅仅只是一个函数,就ok了。

    有状态组件

    ​ 有状态组件就是不但外部可以传入,内部也有state。

    ​ 有状态组件也可以理解为容器组件,用来容纳展示组件,在容器组件里处理数据的逻辑,把结果在展示组件里呈现。容器组件也叫智能组件

    ​ 创建有状态组件如下:

    class Home extends React.Component { //容器组件
        constructor(props) {
            super(props);
      		this.state={
      			Hots:[],
           		Goodslist:[]
    		}
    	}
    	
        getHots(){
            发送axios请求获取数据
        }
    
        getGoodsList(){
           发送axios请求获取数据
        }
        render() {
            return (
    		 
    //展示组件 //展示组件
    ) } }

    注意:

    做项目时,经常会把有状态组件和无状态组件进行结合使用。

    1)、 有状态组件:一般会使用类组件,处理数据的业务逻辑,包括和后端进行交互,获取数据。把数据传给无状态组件

    2)、 无状态组件:一般会使用函数式组件,只做展示用,没有自己的数据,会接收有状态组件传来的数据。

    事件处理

    React事件的特点:

    1、React 事件绑定属性的命名采用驼峰式写法,而不是小写。如:onClick。

    2、如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM 元素的写法)

    3、阻止事件的默认行为,不能使用return false, 必须使用 preventDefault。

    4、事件处理函数里的this是undefined(啊………),如果希望事件处理函数里的this是React组件对象本身,则需要用bind。

    事件语法

    1、格式

    示例:

    class Home extends React.Component{ 
            
        
    fn01() { 
            
      console.log("fn01");
    }
        
    render(){ 
            
      return (
       <div>
         <input type="button" value="测试01" onClick={ 
            this.fn01} />
         <input type="button" value="测试02" onClick={ 
            ()=>{ 
            console.log("事件绑定箭头函数")}} />
        </div>
      )
    }
    }
    

    2、事件处理函数里的this

    事件处理函数里的this是undefined,如何让事件处理函数里的this是React组件对象本身

    一、使用bind
    1)、构造器(构造函数)里:this.方法=this.方法.bind(this)  
    2)、在事件绑定时写,onClick={this.方法.bind(this)}
    
    二、使用箭头函数
    3)、定义方法时,直接使用箭头函数: 方法=()=>{箭头函数定义方法}  
    4)、事件绑定时,使用箭头函数:onClick={()=>this.方法()}
    

    如:

    class MyPerson extends React.Component{
    	constructor(props){
    		super(props);
    		this.state={
    			age:12,
    			isAdult:"未成年"
    		}
    		this.changeAge = this.changeAge.bind(this);
    	}
    
    	changeAge(){
    		………………………………
    	}
    	//直接使用箭头函数
    	changeAge=()=>{
    		this指向会找上一级
    	}
    
    	render(){
    		return (
    			
    {this.changeAge()}} />

    年龄:{this.state.age}

    年龄:{this.state.isAdult}

    ); } }

    3、事件对象

    event对象是经过react处理过的。

    如何获取事件对象------直接声明即可。

    实例方法(ev) ev 代理事件对象 ,ev.target 返回真实DOM

    事件对象的获取:

    1)、直接声明(没有其它参数的情况下)

    changeAge1=(ev)=>{
        console.log(ev);
        console.log(ev.target);
    }
    
    this.changeAge1(ev)} />
    
    

    2)、箭头函数里直接声明(有其它参数的情况下)

    changeAge2(ev,num){
        console.log(ev);
        console.log(ev.target);
        console.log(num);
    }
    //注意:给onClick绑定的函数,还是只有一个参数,这个参数就是事件对象,此处在绑定的函数里再调用另外一个函数进行传参
    this.changeAge2(ev,2)} />
    

    注意:给事件属性绑定的函数,永远只会有一个参数,该参数就是事件对象。

    4、阻止浏览器的默认行为:

    ​ 只能用preventDefault,不能在事件函数里使用return false

    组件的内容 :children

    组件的内容,使用 props.children属性获取

    
    function Button(props) { 
            
      console.log("props",props);
      return (
        <>
          <div>Button_children:{ 
            props.children}</div>
        </>
      )
    }
    
    <Button >我是内容</Button>
    

    refs

    ​ 获取DOM的。

    ​ 表示对组件真正实例(也就是html标签,也就是DOM对象)的引用,其实就是ReactDOM.render()返回的组件实例;ref可以写在html官方标签里,也可以写在组件(自定义标签里),和vue的ref是同样的意思。

    ​ 官方建议: 勿过度使用 Refs(尽量不要操作DOM),在对逻辑进行处理的时候尽量优先考虑state(数据驱动)

    用法

    1). 赋值为 字符串(官方不推荐使用)

      
     
       this.refs.username.value
    

    2). 赋值为 回调函数

    ​ 当给 HTML 元素添加 ref 属性时,ref 回调接收了底层的 DOM 元素作为参数。

    ​ ref 回调会在componentDidMount 或 componentDidUpdate 这些生命周期回调之前执行。

    //ref的值赋成回调函数时,回调的参数就是当前dom元素。
    // callback refs  回调
    
     this.定义一个实例属性 = el} //el就是dom对象
        
        
    this.定义一个实例属性 //后期用作访问jsx元素
    //当组件挂载时,将 DOM el元素传递给 ref 的回调
    //当组件卸载时,则会传递 null。
    //ref 回调会在 componentDidMount 和 componentDidUpdate 生命周期之前调用
        
        如:
       this.input1  = currDom} />
       this.input2 = currDom} />
    

    3). React.createRef() (React16.3提供)

    ​ 使用此方法来创建ref。将其赋值给一个变量,通过ref挂载在dom节点或组件上,该ref的current属性将能拿到dom节点或组件的实例

    //1、在构造函数里
    // 实例化了ref对象
    this.firstRef = React.createRef() //发生在构造器
    
    //2、挂载在ref属性上
    
        
    //3、获取dom原始
    this.firstRef.current //current是官方的属性
    

    受控元素(组件)

    一个标签(组件)受react中控制,受数据,受函数,等等(其实,就是一个标签(组件)里用了react里的东西)

    表单的value受控,受数据控制,

     //model 控制 view。
       //view 控制 model
    

    双向绑定

    class MyCom extends React.Component{
    		constructor(){
    			super();
    			this.state={
    				username:"李祥"
    			}
    		}
    
    		changeVal(e){
    			this.setState({
    				username:e.target.value
    			})
    		}
    
    		render(){
    			return (
    				
    this.changeVal(e)} />
    ) } }

    处理多个输入元素(双向绑定的封装)

    可以为每个元素添加一个 name 属性(通常和数据名一致),处理函数根据 event.target.name 的值来选择要做什么

    class MyCom extends React.Component{
        constructor(props){
            super(props);
            this.state={
                userName:'',
                content:''
            }
        }
    
        changeVal(ev){
            this.setState({
                [ev.target.name]:ev.target.value
            });
        }
    
        render(){
            return (
                

    {this.state.userName}

    this.changeVal(ev)} />

    {this.state.content}

    this.changeVal(ev)} />
    ) } }

    非受控元素(组件)

    ​ 要编写一个非受控组件,而不是为每个状态更新都编写数据处理函数,你可以 使用 ref 来从 DOM 节点中获取表单数据

    
    

    默认值

    ​ 表单元素上的 value 将会覆盖 DOM 节点中的值,在非受控组件中,你经常希望 React 能赋予组件一个初始值,但是不去控制后续的更新,指定一个 defaultValue 属性,而不是 value

    可选案例:

    增删改查

    生命周期及其钩子函数

    react组件生命周期经历的阶段:初始化阶段 -----> 运行阶段(更新期)-----> 销毁阶段

    初始化阶段 (挂载):(在这个阶段完成了vue中数据挂载和模板渲染)

    组件实例被创建并插入 DOM 中时,其生命周期钩子函数的调用顺序如下(粗体为使用比较多的):

    1)、constructor

    ​ 构造函数里,可以做状态的初始化,接收props的传值

    2)、componentWillMount: 在渲染前调用,相当于vue中的beforeMount

    3)、render

     渲染函数,不要在这里修改数据。 vue中也有render函数。
    

    4)、componentDidMount 相当于vue中的 mounted

    ​ 渲染完毕,在第一次渲染后调用。之后组件已经生成了对应的DOM结构, 如果你想和其他JavaScript框架(swiper)一起使用,可以在这个方法中使用,包括调用setTimeout, setInterval或者发送AJAX请求等操作,相当于vue的mounted

    运行中阶段(更新)(相当于vue中更新阶段)

    当组件的 props 或 state 发生变化时会触发更新(严谨的说,是只要调用了setState()或者改变了props时)。组件更新的钩子函数调用顺序如下:

    1)、shouldComponentUpdate(nextProps, nextState) 是否更新? 需要返回true或者false。如果是false,那么组件就不会继续更新了。

    2)、componentWillUpdate,即将更新。相当于vue中的 beforeUpdate

    3)、 componentWillReceiveProps(nextProps): 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。nextProps 是props的新值,而 this.props是旧值。相当于vue中的 beforeUpdate

    4)、render

    ​ 不要在这里修改数据

    5)、componentDidUpdate。相当于vue中的 updated

    在组件完成更新后立即调用。在初始化时不会被调用。 相当于vue中的updated

    销毁阶段(卸载)

    componentWillUnmount()

    即将卸载,可以做一些组件相关的清理工作,例如取消计时器、网络请求等

    示例:

    
    class MyPerson extends React.Component{ 
            
    	constructor(props){ 
            
    		super(props);
    		console.log("====constructor===");
    		this.state={ 
            
    			age:12
    		}
    	元器件数据手册IC替代型号,打造电子元器件IC百科大全!
              

    相关文章