React基础

React

是跟 Vue 很相似的一套框架,它是Facebook写的
框架特点:

  • 声明式
  • 组件化

安装

react.js - React 的核心库

react-dom.js - 提供与 DOM 相关的功能

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

引入文件,必须先引react.js再引react-dom.js

<script src="../js/react.js"></script>
<!-- 提供全局的 React变量 -->
<script src="../js/react-dom.js"></script>
<!-- 提供全局的 ReactDOM变量 webpack  -->
<script src="../js/babel.js"></script>

使用

<script type="text/babel"><script>中使用JSX(JS+HTML)语法
基本使用

react.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
	<!-- View -->
    <div id="demo"></div>
    <script src="../js/react.js"></script>
    <script src="../js/react-dom.js"></script>
    <script src="../js/babel.js"></script>
    <!-- JSX语法 script标签里面写的都是JSX语法,所以要设置type="text/babel"通知babel.js帮你把JSX转为JS -->
    <script type="text/babel">
        // react-dom提供的ReactDOM的render方法来渲染DOM结构
        // render: ƒ (element, container, callback) 
        // element:HTML结构模板 container:选择器,会把结构渲染到选择器选中的结构中
        
        // Model
        // React是单向数据绑定的 
        // 视图变数据不变,这是react和vue的最大区别之一
        // vue借助v-model,@xxx,v-on:xxx,才可以完成视图更改,数据变化
        // react是没有任何指令的,所以要V->M是没有v-model,只有事件这种方法
        
        ReactDOM.render(
            <div>
                <p>katsuki</p>
            </div>,
            document.querySelector("#demo")
        )
    </script>
</body>
</html>

声明式语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
</head>
<body>
    <div id="demo"></div>
    <script src="../js/react.js"></script>
    <script src="../js/react-dom.js"></script>
    <script src="../js/babel.js"></script>
    <!-- react: View = Render(Model) -->
    <script type="text/babel">
        let data = {
            name:"katsuki",
            obj:{
                age:18
            },
            arr:[
                <li key='1'>ka</li>,
                <li key='2'>tsu</li>,
                <li key='3'>ki</li>
            ],
            num: 16,
            bool:true,
            html: `
                <p style="color:red">kasami</p>
            `
        }
		let methods = {
            renderString(){
                return "katsuki desu"
            }
        }
        /*
        	style接受的是对象,相当于`v-bind:style`或者`:style`
            <p style={{
                color: "pink",
                fontSize: "18px"
            }}></p>
        */

        // <p name={data.name}></p>  相当于vue里面的v-bind:xxx

        // {data.arr}会把数组遍历渲染出来

        /*
            <div dangerouslySetInnerHTML={{__html:data.html}}></div>
            插入HTML结构可能夹带恶意代码导致程序崩溃
            有被攻击的风险,故取名dangerouslySetInnerHTML
            只变动data.html部分,其他是规定写法
        */

		// 最后两个标签为函数使用
        ReactDOM.render(
            <div>
                <p style={{
                    color: "pink",
                    fontSize: "18px"
                }}>{data.name}</p>
                <p name={data.name}>{data.obj.age}</p>
                <p>数组</p>
                <ul>{data.arr}</ul>
                <p>{data.num+1}</p>
                <p>{data.bool?'真':'假'}</p>
                <div dangerouslySetInnerHTML={{__html:data.html}}></div>
                <p>{methods.renderString()}</p>
                <p>{
                    (function() {
                        return "muda muda"
                    })()
                }</p>
            </div>,
            document.querySelector("#demo")
        )
    </script>
</body>
</html>

外层结构同上述例子,下面例子只写<script type="text/babel"></script>中的内容和一些样式内容

用声明式来替代指令

大括号就叫声明式渲染,vue中的{{}}只能放变量,react中的{}可以放函数,由于react不像vue有指令,所以会在声明式中写函数来替代指令,甚至编写自己想要的功能。

模拟v-text&v-html

let data = {
    name:"katsuki",
    html:`
        <p style="color:red">kasami</p>
    `
}
let methods = {
    vText(params){
        return params
    },
    vHtml(html){
        return <div dangerouslySetInnerHTML={{__html:html}}></div>
    }
}
ReactDOM.render(
    <div>
        <p>v-text</p>
        <p>
            {
                methods.vText(data.name)
            }
        </p>
        <p>v-html</p>
        <p>
            {
                methods.vHtml(data.html)
            }
        </p>
    </div>,
    document.querySelector("#demo")
)

模拟v-for

let data = {
    name:"katsuki",
    arr:[
        <li key="1">ka</li>,
        <li key="2">tsu</li>,
        <li key="3">ki</li>
    ],
    // 只要把arr2构造成arr的数组格式,就可以在声明式渲染里面显示该列表
    arr2:['ka','tsu','ki']
}
let methods = {
    vFor(arr){ 
        return arr.map((item,index)=>{
            return <li key={index} name={"li-"+item}>{item}</li>
        })
         
    }
}
ReactDOM.render(
    <div>
        <p>v-for</p>
        <ul>
            {
                data.arr
            }
        </ul>
        <ul>
            {
                methods.vFor(data.arr2)
            }
        </ul>
    </div>,
    document.querySelector("#demo")
)

模拟v-bind

let data = {
    name:"katsuki",
    size:50,
    styleObj:{
        color:'blue',
        fontSize:`48px`
    }
}
let methods = {
    styleObj(){
        return {
            color:'yellow',
            fontSize:`32px`
        }
    }
}
ReactDOM.render(
    <div>
        <p>v-bind</p>
        <p data-name={data.name}>{`类名:`+data.name}</p>
        
        <p>v-bind:style</p>
        <p style={{
            color:'pink',
            fontSize:`${data.size}px`
        }}>katsuki</p>
        
        <p>v-bind:style</p>
        <p style={
            data.styleObj
        }>kasami</p>
        
        <p>v-bind:style</p>
        <p style={
            methods.styleObj()
        }>Grisaia</p>
    </div>,
    document.querySelector("#demo")
)

模拟v-bind:class&v-show

<style>
    .pink{
        color:pink;
    }
    .red{
        color:red;
    }
    .size{
        font-size: 14px;
    }
</style>
<script type="text/babel">
     let data = {
         bool:true
     }
     /*
		在jsx中写class for属性值是关键字,直接写会冲突
		需要分别改成className htmlFor
	*/ 
     ReactDOM.render(
         <div>
             <p>v-bind:class</p>
             {/*<label htmlFor></label>*/}
             <p className={
                 data.bool?'pink':'red'
             }>katsuki</p>

             <p>v-show</p>
             <p style={{
                 display:data.bool?'block':'none'
             }}>kasami</p>
         </div>,
         document.querySelector("#demo")
     )
</script>

模拟v-if

let data = {
	bool: true
}
let methods = {
	vIf(bool){
		if(bool,html){
			return html;
		}
	}
}
ReactDOM.render(
	<div>
		<p>v-if</p>
		{
		    (function(bool) {
		        if(bool){
		            return <p>katsuki</p>
		        }
		    })(data.bool)
		}
		<p>v-if</p>
		{
		    methods.vIf(!data.bool,<p>kasami</p>)
		}
	</div>,
	document.querySelector("#demo")
)

模拟v-on

监听事件,原生的写法onclick而react需要on之后的那个字母大写onClick

原生ReactVue
onclickonClick@click/v-on:click
onchangeonChange
onkeyuponKeyup
let data = {
    name: 'katsuki',
    age: 18
}
let methods = {
    boChi(age,name,e){
        console.log(age,name,e.target)
    }
}
// 注释
ReactDOM.render(
    <div>
        <p>v-on</p>
        <button onClick={
            ()=>{
                console.log('katsuki desu')
            }
        }>OK</button>
        
        {/*
       		methods.boChi 不传参执行
       		methods.boChi()会不等待点击直接执行,不符合原本意图
       		methods.boChi.bind(this) 这里的this指向当前节点button
		*/}
        <button onClick={
            methods.boChi.bind(this,data.age,data.name)
        }>OK</button>  
    </div>,
    document.querySelector("#demo")
)

组件

函数式组件

纯展示组件,这种组件只负责根据外部传入的props来展示,书写简洁,执行效率更高

  • 特点
    1. 无state状态,只能访问传入的props属性
    2. 组件不会被实例化,整体渲染性能得到提升
    3. 组件不能访问this对象
    4. 组件无法访问生命周期的方法
<style>
    *{
        margin: 0;
        padding: 0
    }
    header{
        width: 100%;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background: gray;
        color: pink;
    }
</style>
<script type="text/babel">    
    // 正常方式
    let Xkatsuki = (props) =>{
    	// 父组件传入值存入props
    	console.log(props)
        return <header>{props.title}</header>
    }
    // 解构方式
    let Xkatsuki = ({title}) =>{
        return <header>{title}</header>
    }
    
    ReactDOM.render(
        <div>
            <Xkatsuki title="ka"/>
            <Xkatsuki title="tsu"/>
            <Xkatsuki title="ki"/>
            {
	            ((title) => {
	                return <header>{title}</header>
	            })("底部组件")
            }
        </div>,
        document.querySelector("#demo"),
        ()=>{
            console.log('katsuki desu')
        }
    )
</script>

类组件

类继承组件有丰富的特性(state状态、生命周期等)

<style>
    *{
        margin: 0;
        padding: 0
    }
    header{
        width: 100%;
        height: 50px;
        line-height: 50px;
        text-align: center;
        background: gray;
        color: pink;
    }
</style>
<script type="text/babel">
    // 类组件
    // 所有自定义组件都继承于React.Component,因为要继承一些React组件的基本方法
    // 定义组件不要 div,header,p,组件首字母必须要大写
    // 构造函数规范首字母大写
    // 类组件 = 构造组件 = 构造函数声明的组件
    class Xkatsuki extends React.Component{
        constructor(props){
        	// 在类继承的构造函数中,要使用this,必须先执行super()
	        // 执行super()后才有this对象
	        super();// React.Component.call(this)
            console.log(props)
            this.props = props
        }
        render(){
            return (
                <header>{this.props.title}</header>
            )
        }
    }
    console.log(Xkatsuki)
    let data = {
        title1: "ka"
    }
    ReactDOM.render(
        <div>
            {/*props就是可以让组件呈现不同状态,而它的本质就是父组件(容器)把值传给子组件*/}
            <Xkatsuki title={data.title1} age="18" skill="[js,html,css]" />
            <Xkatsuki title="tsu" />
            <Xkatsuki title="ki" />
            {
                ((title) => {
                    return <header>{title}</header>
                })("底部组件")
            }
        </div>,
        document.querySelector("#demo"),
        ()=>{
            console.log('katsuki desu')
        }
    )
</script>

state

state=>状态(数据模型),状态(数据)决定视图

// State -> View    React
// data(model) <-> View   Vue
class Xkatsuki extends React.Component{
    constructor(props){
        super(props)
        console.log(props)
        //父传过来的数据
        this.props = props
        //组件自身数据
        //Model
        this.state = {
            name: "katsuki"
        }
    }
    render(){
        return (
            <div>
                <p style={{
                    color:'pink'
                }}>props 父给的</p>
                <p>{this.props.title}</p>

                <p style={{
                    color:'pink'
                }
                }>state 自身给的</p>
                <p>{this.state.name}</p>
            </div>
        )
    }
}

ReactDOM.render(
    <div>
        <Xkatsuki title="ka" age="18" />
        <Xkatsuki title="tsu" />
        <Xkatsuki title="ki" />
    </div>,
    document.querySelector("#demo")
)

setState

> v-model(vue) = onChange + setState(react)

react的语法是{},单向数据绑定
vue的语法是{{}},双向数据绑定

vue中
1. data变了,view层通过v-xxx或者{{}}指令,来渲染数据  M->V
2. view变了,你通过v-on或者v-model来把数据从视图层带回数据层  V->M

react中
1. data变了,是通过函数式编程和{},来渲染数据  S->V
2. view变了,通过事件触发setState来更改数据层  V->S
// State -> View    React
// data(model) <-> View   Vue
class Xheader extends React.Component{
    constructor(props){
        super(props)
        //父传过来的数据
        this.props = props
        //组件自身数据
        //Model
        this.state = {
            name: "katsuki"
        }
    }
    setValue(e){
        console.log(this)
        // e.target.value帮助完成把V的数据带回给M层
        // V->M
        // 配合事件和setState
        this.setState({
            name:e.target.value
        })
    }
    render(){
        return (
            <div>
                {/*onChange={this.setValue.bind(this)} bind中this指向Xheader*/}
                <input onChange={this.setValue.bind(this)} value={this.state.name} />
                <p style={{
                    color:'pink'
                }
                }>state 自身给的</p>
                <p>{this.state.name}</p>
            </div>
        )
    }
}

ReactDOM.render(
    <div>
        <Xheader title="kasami" age="18" />
    </div>,
    document.querySelector("#demo")
)

组件引入

项目结构
	components
		Xkatsuki.jsx
	js
	index.html
index.html body部分
<body>
    <div id="demo"></div>
    <script src="./js/react.js"></script>
    <script src="./js/react-dom.js"></script>
    <script src="./js/babel.js"></script>
    <script type="text/babel" src="./components/Xkatsuki.jsx"></script>
    <script type="text/babel">
        ReactDOM.render(
            <div>
                <Xkatsuki />
            </div>,
            document.querySelector("#demo")
        )
    </script>
</body>
Xkatsuki.jsx
class Xheader extends React.Component{
    constructor(props){
        super(props)
        this.props = props
    }
    render(){
        return (
            <header>katsuki</header>
        )
    }
}

本地打开会有下图错误
在这里插入图片描述
file协议引入jsx的script标签会跨域,需要在服务器环境下运行,比如搭建一个express脚手架,把文件放到public文件夹中,npm start运行服务,详情参考博文Node_express

生命周期

生命周期VueReact描述
编译前beforeCreate-数据和虚拟DOM和真实DOM都没有
编译后createdconstructor有数据
挂载前beforeMountcomponentWillMount有数据,有虚拟DOM,但没挂载
挂载后mountedcomponentDidMount有数据,有虚拟DOM,有挂载
更新前beforeUpdatecomponentWillUpdate更新数据,并且更新了虚拟DOM,但没挂载
更新后updatedcomponentDidUpdate真实DOM更新了
销毁前beforeDestory-虚拟DOM销毁了,但真实DOM没销毁
销毁后destoryedcomponentWillUnmount真实DOM销毁了
-shouldComponentUpdate组件只要更新,就会触发这个生命周期,return 布尔值,为真DOM更新,否则不更新

componentWillReceiveProps:这是接收新的props时候调用的生命周期

componentWillReceiveProps(nextProps) {
	const { getPropsData } = nextProps;
	console.log(getPropsData);
}

shouldComponentUpdate使用案例

<body>
	<div id="demo"></div>
    <script src="../js/react.js"></script>
    <script src="../js/react-dom.js"></script>
    <script src="../js/babel.js"></script>
    <script type="text/babel">
        class Xheader extends React.Component{
            constructor(props){
                super(props)
                this.props = props
                this.state = {
                    name: "katsuki"
                }
            }
            setValue(e){
                this.setState({
                    name:e.target.value
                })
            }
            shouldComponentUpdate(){
                // 如果返回true,页面更新,否则不更新
                // 输入框输入内容长度大于7时,DOM不更新
                if(this.state.name.length>7){
                    return false
                }else{
                    return true
                }
            }
            render(){
                return (
                    <div>
                        <input onChange={this.setValue.bind(this)} value={this.state.name} />
                        <p style={{
                            color:'pink'
                        }
                        }>state 自身给的</p>
                        <p>{this.state.name}</p>
                    </div>
                )
            }
        }

        ReactDOM.render(
            <div>
                <Xheader title="katsuki" />
            </div>,
            document.querySelector("#demo")
        )
    </script>
</body>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值