React入门(一)之基本语法(内容较多)

vuereact作为当下前端最主流的两大框架,当然需要学习啦!
还没有学过vue的可以去我之前的博客vue入门系列!!

一、介绍React

1.1、简介

  1. React 是一个用于构建用户界面的 JAVASCRIPT 库。
  2. React主要用于构建UI。
  3. React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
  4. React 拥有较高的性能,代码逻辑非常简单。

1.2、特点

简单概述下:

1)高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
2)灵活 −React可以与已知的库或框架很好地配合。
3) JSX − JSX 是 JavaScript 语法的扩展。
4) 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

​ 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,也正因此,它比传统数据绑定更简单。

1.3、与其他框架对比

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

相同点是:都采用虚拟dom,和数据驱动

二、搭建环境

2.1、通过引入文件的方式

<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    
  //第一个react程序
   ReactDOM.render(
       <p>第一个react程序</p>,
       document.getElementsByClassName('box')[0]
   )

</script>

引入的三个js文件:

2.2、通过官方脚手架的方式

  1. 安装create-react-app
npm install create-react-app -g
  1. 创建 react项目
create-react-app 目录 | npm init react-app 目录
npm start 	开发
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。

2.3、第三方脚手架

yeomen/dva/umi

三、JSX

首先,我们开始编写第一个react程序:(前面其实展示过)

<body>
    <div class="box">
        
    </div>
</body>
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    
    //第一个react程序
    ReactDOM.render(
        <p>第一个react程序</p>,
        document.getElementsByClassName('box')[0]
    )

</script>

注意:script标签的type取值为:text/babel

页面显示效果:

在这里插入图片描述

3.1、ReactDOM.render()函数

在程序中,我们可以看到通过 ReactDOM.render()函数,将p标签渲染到了类名为box的标签中。

那么,ReactDOM.render()函数是什么??

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

基本格式:

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

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


那么,JSX是什么?

3.2、JSX介绍

JSX就是Javascript和XML结合的一种格式。是 JavaScript 的语法扩展,只要你把HTML代码写在JS里,那就是JSX

3.3、JSX特点

​ 1) JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
​ 2)它是类型安全的,在编译过程中就能发现错误。
​ 3)使用 JSX 编写模板更加简单快速。

3.4、JSX的语法

所谓语法就是把html代码写在javascript中的要求规范。

3.4.1、XML基本语法

  • 只能有一个根标签,外面加上圆括号。

  • 标签要闭合(单标签要加斜杠)

<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    
    ReactDOM.render(
    //此处只有一个根标签div,否则会报错,如下图
        <div>
            <input type="button" value={msg2}/>{/*单标签必须以‘/’结尾*/}
        </div>,
        document.getElementsByClassName('box')[0]
    )
</script>

在这里插入图片描述

3.4.2、元素类型

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

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

<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    ReactDOM.render(
       <div>
           <p>第一个react程序</p>{/*此处为注释*/}
       </div>,
       document.getElementsByClassName('box')[0]
   )
</script>

3.4.3、元素属性

  • 内联样式的style:样式名以驼峰命名法表示, 如font-size需写成fontSize。默认像素单位是 px(px不用写)
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    let sty = {backgroundColor:'red',
    			fontSize:24,
    			width:200,
    			height:100}
    			
    ReactDOM.render(
        <div>
        {/*此处style的值直接用单花括号,不用加引号*/}
            <p style={sty}>第一个react程序</p>{/*样式style直接用单花括号*/}
        </div>,
        document.getElementsByClassName('box')[0]
    )
</script>
  • 外部样式的class:HTML中曾经的 class 属性改为 className(因为class是js的关键字),外部样式时使用
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    ReactDOM.render(
        <div>
            <div className="box2">{msg}</div>{/*类名class关键字用className代替*/}    
        </div>,
        document.getElementsByClassName('box')[0]
    )
</script>
  • for 属性改为 htmlFor(因为for是js的关键字)。(for属性在html标签中是扩充单选框|复选框的选择范围)
  • 事件名用驼峰命名法。HTML是全小写(onclick),JSX中是驼峰(onClick)
<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
    
    function add(){
        msg2 = '我是按钮2'
        console.log('msg2:',msg2);
    }

    ReactDOM.render(
        <div>
        {/*此处onclick写为onClick,驼峰命名法*/}
            <p onClick={add}>点击我改变按钮的值</p>{/*事件名驼峰命名法*/}
        </div>,
        document.getElementsByClassName('box')[0]
    )

</script>

3.4.4、javascript表达式

  • 使用单花括号
    react里没有vue中的指令,任何地方需要javascript的变量,表达式等等,只需要套上 单花括号就行
const element = <h1>Hello, {120+130}!</h1>
const element = <h1>Hello, {getName("张三疯")}!</h1>

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

四、条件渲染

就是普通的js条件判断语句。

<script src="../js/react.js"></script>
<script src="../js/react-dom.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">

    let num = 23;
    if(num>=18){
        var htmlStr = <p>我成年了</p>
    }else{
        var htmlStr = <p>我是未成年</p>
    }

    ReactDOM.render(
        <div>
            {htmlStr}
        </div>,
        document.getElementById('box')
    )

</script>

五、列表渲染

5.1、渲染数组

//数组里存放jsx
var arr=[
    <li>张三疯</li>,
    <li>张四疯</li>,
    <li>张五疯</li>
]

const show = ()=> (
    <ul>{arr}</ul>
)
ReactDOM.render(show(),document.getElementById("box"));

5.2、map()或者普通for循环

let arr = [
        '平凡的世界',
        '麦田里的守望者',
        '最后一滴眼泪',
        '活着'
    ]
   
ReactDOM.render(
    <div>
        {arr.map(item=>(<p>书名:《{item}</p>))}
    </div>,
    document.getElementById('box')
)

六、组件

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

6.1、函数组件

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

//函数组件
   function Vid(){
       return <p>
               我是函数组件
              </p>
   }

ReactDOM.render(
    <div>
        {Vid()}//通过调用函数使用
        <Vid></Vid>//直接作为标签使用
    </div>
    ,
    document.getElementById('box')
)

6.2、类组件

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

换句话说:一个普通的ES6的类,只要有一个render()函数,并且render()函数返回一个JSX,那么就是组件。

//类组件
class Vid extends React.Component{
    render(){
        return <p>我是类组件</p>
    }
}

ReactDOM.render(
    <div>
        <Vid></Vid>//直接作为标签使用
        {(new Vid()).render()}//实例对象并调用render方法使用
    </div>
    , 
    document.getElementById('box')
)

6.3、ES5的写法(React16后,已经废弃)

React.CreateClass()函数

var MyCom = React.createClass({  
  render:function(){ //vue中也有render函数,是完成模板的代码
    return (
      <div>
        <h1>Hello, world!</h1>
      </div>
    );
  }
});

6.4、多组件

// 标题
function MyTitle(){
	return (
		<h1>商品列表</h1>
	)
}
// 详情
function MyDetail(){
	return (
		<ul>
			<li>铅笔</li>
			<li>钢笔</li>
		</ul>
	)
}

ReactDOM.render(
	<div>
		<MyTitle/>
		<MyDetail/>
	</div>,
    document.getElementById('box')
);

七、props

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

7.1、外部传值

<组件名 属性名1=1 属性名2=2 .. />
ReactDOM.render(
     <div>
        <Vid msg="我是传过去的props" data="附加信息"></Vid>
     </div>
     , 
     document.getElementById('box')
)

7.2、组件内部使用

7.2.1、函数组件内部使用

{props.属性名}
//函数组件
function Vid(props){
 //    let msg = '我是函数组件plus'
 console.log(props);
    return <div>
             <p>{props.msg}</p>
             <p>{props.data}</p>
         </div>
}

在这里插入图片描述

7.2.2、类组件内部使用

{this.props.属性名}
//类组件
class Vid extends React.Component{
    constructor(props){
        super()
        this.props = props
     //    console.log('this.props:',this.props);
     console.log('this.props:',this.props);

    }
    render=()=>{
        //此处要箭头函数,因为内部this指向改变了
        return (<div>
             <p>姓名:{this.props.name}</p>
         </div>)
    }
 }

此处注意:
在类的constructor里直接打印props是undefined

在这里插入图片描述
若要获得传入的参数,需要加一句

 this.props = props(props为构造函数的形参)

在这里插入图片描述

7.2.3、props传入对象

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

  • 传对象
let obj = {
        name:'华为手机',
        price:'4800元',
        color:'深空蓝',
    }

ReactDOM.render(
    <div>
       <Vid {...obj}></Vid>
    </div>
    ,
    document.getElementById('box')
)
  • 组件内部使用
//类组件
class Vid extends React.Component{
    constructor(props){
        super()
        this.props = props
     //    console.log('this.props:',this.props);
     console.log('this.props:',this.props);

    }
    render=()=>{
        //此处要箭头函数,因为内部this指向改变了
        return (<div>
             <p>名字:{this.props.name}</p>
             <p>价格:{this.props.price}</p>
             <p>颜色:{this.props.color}</p>
         </div>)
    }
 }

7.2.4、props的默认值

1)、用 ||

function MyPerson(props){
//当没有传sex时值为女
	let sex1 = props.sex || "女";
	return (
		<div>
			<p>性别:{sex1}</p>
		</div>
	)
}

2)、defaultProps

格式:

//1)、函数式组件和类组件都可以:

组件名.defaultProps={

    属性名: 默认值

}

//2)、若为类组件,可以在类的内部使用static修饰。

static defaultProps={
    属性名: 默认值
}

函数组件使用defaultProps:

function Vid(props){
        return <div>
                她叫{props.name},今年{props.age}</div>
    }

    Vid.defaultProps = {
        name:'晓晓',
        age:'23'
    }

    ReactDOM.render(
        <div>
           <Vid age="18"></Vid>
        </div>
        ,
        document.getElementById('box')
    )

效果图:

在这里插入图片描述

7.2.5、类型检查

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

//类型约定:
组件名.propTypes={	
    属性名1:PropTypes.类型名,
    属性名2:PropTypes.类型名
}

//必传参数
propName: PropsTypes.类型名.isRequired
类型名的可以取值为:

PropTypes.array,
PropTypes.bool,
PropTypes.func,
PropTypes.number,
PropTypes.object,
PropTypes.string,
PropTypes.symbol,
function MyPerson(props){
	return (
		<div>
			<p>年龄:{props.age}</p>
		</div>
	)
}

MyPerson.propTypes={
    //注意大小写
	age:PropTypes.number.isRequired
}

ReactDOM.render(
	<MyPerson age={12} />,
	document.getElementById('box')
);

八、state状态机

state 是状态,状态就是数据,state表示组件的内部数据。而props是外部传入组件的数据类似vue中的data

8.1、定义并初始值

//类组件
   class Vid extends React.Component{
       constructor(props){
            super()
            //构造函数里定义并初始化
            this.state = {
                age:13
            }

       }
       render=()=>{
           //此处要箭头函数,因为内部this指向改变了
           return (<div>
                {/*获取state里的age*/}
                <p>年龄:{this.state.age}</p>
            </div>)
       }
    }


    ReactDOM.render(
        <div>
           <Vid></Vid>
        </div>
        ,
        document.getElementById('box')
    )

8.2、读取状态

this.state.属性名

8.3、修改状态

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

  • 1、修改状态时,必须要调用setState。因为,只要调用了setState函数,那就会调用了render()。如果直接赋值,不会把数据响应式地渲染到DOM上。(即:没有调render()函数)
//类组件
class Vid extends React.Component{
    constructor(props){
         super()
         this.state = {
             age:13
         }

    }
    render=()=>{
        //此处要箭头函数,因为内部this指向改变了
        return (<div>
             {/*获取state里的age*/}
             <p>年龄:{this.state.age}</p>
             <input type="button" value="点击年龄加1" onClick={()=>this.change()}/>
         </div>)
    }
    change(){
        //改变state里age的值
        this.setState({
            age:18
        })
         
    }
 }


 ReactDOM.render(
     <div>
        <Vid></Vid>
     </div>
     ,
     document.getElementById('box')
 )
  • 2、setState()函数是异步的
change() {
     //改变state里age的值
     console.log('this.state.age:(前)', this.state.age);
     this.setState(function (prevState) {
         console.log('改变状态前干的事');
         return {
             age: 18
         }
     }, function () {
     //改变状态后打印值
         console.log("this.state.age", this.state.age);
     })
     console.log('this.state.age:(后)', this.state.age);
 }

在这里插入图片描述

注意:直接修改state属性的值不会重新渲染组件 ,

  • 补充

    给引用类型的某个属性赋值(也就是this.state里的某个属性值是对象)

change(){        
     this.setState({
         desc:{
                 ...this.state.desc,
                 date:(new Date()).toLocaleString()
             }
     });
 }

今天写了一天的博客!!!

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值