React基础

react入门

简介

react是有Facebook团队建设的于13年5月份开源
react框架定位:只是MVC框架里面的视图层
特点:声明式,组件化,一次学习随处编写
react在16.x版本之后推出fiber协调算法,解决之前的diff算法同步的进行更新操作,导致浏览器卡顿的问题。内部采分片思想实现的

安装

npm i react react-dom babel-standlone
安装所需要的包,然后在node_modules中分别找到相对应的文件夹,将里面的js文件复制到自己新建的js文件中
然后在HTML中引入这些文件

<!-- 引入react核心包 如果需要使用react  这个包必须在最前面 不然后续无法识别react内相关的语法 -->
    <script src="./js/react.development.js"></script>
    <script src="./js/react-dom.development.js"></script> <!-- 注意这里两个js文件的引入顺序一定不能出错 -->
    <script src="./js/babel.js"></script>  //babel包主要就是用来解析jsx代码的

然后就可以使用react来写代码了

<body>
    <div id="app"></div>
    <script type="text/babel">
        // console.log(ReactDOM)
        // jsx代码   JavaScript + xml语法
        //如果要使内容呈现为h2下的样式就需要引入babel(解析jsx代码的包),同时要在script标签上加 type="text/babel"
        //如果没有这些条件的话   页面会报错 “<” 未识别
        ReactDOM.render(<h2>hello  react</h2>,document.getElementById("app"))
    </script>
</body>

ReactDOM.createElement(核心)

jsx内部的原理是什么?

首先jsx内部通过babel将jsx代码进行解析(ReactDOM.createElemnet)–> 虚拟dom ---->ReactDOM.render() 将虚拟dom渲染成真实dom
在这里就要注意一个问题就是,引入babel后再script标签内就要加入type=“text/babel” 这个属性以及属性值

class属性的使用方法

const a = <h2 class="app">H2!!</h2> //如果里面用class属性的话,虽然不影响页面的渲染,但是会报错,会被当成一个保留字,推荐使用className

 const a = <h2 className="app">H2!!<span>SPAN!!<a>A!</a></span></h2> 
 //jsx语法糖  替代React.createElement()
  // 这种写法可以直接不需要babel,但是这样写有个问题就是,当里面嵌套的标签多了以及内容多了之后,写起来会变得很麻烦
 const a = React.createElement("h2",{className:"app"},"H2!!",
React.createElement("span",{},"嵌套在h2里面的SPAN!!",
React.createElement("a",{},"嵌套在span里面的a!!"))) 

ReactDOM.render(a,document.getElementById("app"))
这个必须加,如果不用这个方法的页面上是无法渲染页面的,当然内部的“a”也可以直接用HTML语言代替,但是要遵循一个规则就是其中的标签必须闭合,包括单标签,例如;有且只有一个根元素;jsx内部注释写法为{/* 注释*/}

react内部样式写法

在标签内使用style标签的时候要注意的就是,在这里需要用到的是双大括号(内部的大括号是个对象),同时内部value值需要加单引号,key需要驼峰式命名或者是正常命名但是要加单引号,但是推荐使用驼峰式命名方法,用’text-align’:'center’这种写法页面会报错提醒你换成textAlign

 const a = <div style={{background:'skyblue',color:'red',fontSize:'40px','text-align':'center'}}>style样式使用</div>
       ReactDOM.render(a,document.getElementById("app"))

react表达式

react中可以通过{}方式渲染变量
{}中放入数组会自动进行字符产拼接
{}中放入布尔值,undefined null 页面不会进行渲染直接为空,且不占位
{}中放入对象直接拨错
{}中可以放入函数,但是需要用闭包的形式,也就是(函数声明)(函数调用)

react事件绑定

当两种点击方法同时存在的时候,先触发的是document.getElement(“a”).onclick事件,同时这个方法必须要在放在render之后
如果在render前面的话直接报错,因为此时的页面还没有渲染出div标签,所以也就无法获取到id
利用函数的形式绑定事件的时候,要注意的是在标签内绑定事件的时候用的是驼峰式命名方法,同时引入事件也需要加{}

 function click(){
            alert(1)
        }                
        const a = <div id="a" onClick={click}>我是a</div>
        ReactDOM.render(a,document.getElementById("app"))
        document.getElementById("a").onclick = function(){
            alert(2)
        }

数组的map遍历

[注意!!]下面两个问题可能会是面试题
vue中通过指令v-for可以进行数组或对象的遍历,在react中如何遍历数组?

react里面是没有提供任何指令!
jsx中遍历数组可以通过map方法进行遍历!

数组的遍历迭代需要注意什么?加key?为何加key?

key 帮助 React 识别哪些元素改变了,比如被添加或删除。因此你应当给数组中的每一个元素赋予一个确定的标识。
key值相同的节点是会复用!
key还不容易报错!尽量不要使用index作为下标! 容易有误差,除非index值一直保持不变,同时内部元素不会发生任何改变

const arr = [1,2,3]
        ReactDOM.render(<div>{
            arr.map((item,index)=>{return <p key={index}>{item}</p>})
        }</div>,document.getElementById("app"))
    </script>
多数组遍历

当需要遍历多个数组的时候,可以直接将map方法封装成一个函数,用的时候直接调用就行
【注】在封装函数的时候记住一定要有return返回值,如果没有返回值的话,最后调用的时候值就是undefined,这样页面也就不会进行渲染,同时还要注意的就是,如果return后面不加()的话,那么后面一定要跟着表达式,不然会被判定没有return返回值

const arr = [1,2,3]
        const arr2 = ['a','b','c']
        function mapArr(arr){
           return arr.map(
               (item,index)=>{
                   return <p key={index}>{item}</p>
                })
        }
        ReactDOM.render(<div>
            {
                mapArr(arr)
            }
            {
                mapArr(arr2)
            }
        </div>,document.getElementById("app"))
数组遍历绑定事件

因为react是一个视图层,所以不会像vue一样当数据发生改变后,视图层也跟着数据的改变而重新渲染,所以这时候就需要将ReactDOM.render封装成一个函数,然后绑定在点击事件上,这样每次数据发生了改变后,就要重新在走一遍render函数,这样页面也就完成了重新的渲染,相较于vue来说比较麻烦

let currentIndex = 0
        let arr = ['a','b','c']
        function mapArr(arr){
           return(
                <ul>
                    {
                      arr.map((item,index)=>{return <li key={index}
                                                        className={index == currentIndex?'active' : ''}
                                                        onClick={()=>{currentIndex = index;render()}}
                                                     >{item}</li>})
                    }
                </ul>
           )
        }
       
        render()   //需要调用一次,来渲染初始的页面,如果不调用的话直接渲染不出页面来
        function render() {
            ReactDOM.render(<div>
                {
                    mapArr(arr)
                }
            </div>,document.getElementById("app"))
        }

定义组件方式

函数式

const 组件名(首字母大写)=(props)=>{
                    return jsx表达式             
                }
 注意:组件名的首字母必须大写

利用组件定义,可以在其内部做一些类似于vue中v-show和v-if的操作
之所以是下面的写法的原因可以参考map数组遍历中的事件绑定,主要原因就是因为react只是一个视图层没有双向数据绑定,无法实时监听到数据的改变
第一种显示隐藏的写法,第二种请看class组件定义

let isShow = true    //注意,这里不能用const去定义要修改的变量,因为const定义的变量不能修改
            const App = (props) => {
                return (
                    <div>
                        <button onClick={()=>{isShow=!isShow;render()}}>切换</button>
                        <div className={isShow? 'block' : 'none'}>我是APP组件</div>
                    </div>
                )
            }  
            render()  
            function render(){
                ReactDOM.render(<App/>,document.getElementById("app"))
            }
函数式定义组件中的属性

注意:组件名的首字母必须大写,这里面不需要this,直接使用传参拿数据就ok

const App = (props) => {
         console.log(this)  //undefined  是没有属性的
            return (
                <div>
                    APP组件 --- {props.name}
                </div>
            )
        }  
        
        let obj = {
            name:"张三",
            age:10,
            sex:"男"
        }
        //可以在<App name={"张三"}/>中直接添加
        render()
        function render(){
            ReactDOM.render(<App {...obj}/>,document.getElementById("app"))
        }

class定义组件

两种组件方式:第二种,class定义
                class 组件名  extends  React.Component {
                    render(){ //render是必不可少的钩子函数
                        return jsx表达式
                    }
                }

这是第二种显示隐藏写法,第一种在函数式写法里面

let isShow = true
            class App extends React.Component{
                render(){  //render这个钩子函数必须要有
                    return (
                        <div>
                            <button onClick={()=>{isShow=!isShow;render()}}>切换</button>
           {/*这是第二种写法,不需要用className了直接用style属性就可以,需要注意的就是要双括号,这里模拟的是vue中的v-show指令*/}
           {/*<div style={{display:isShow? 'block' : 'none'}}>我是APP组件</div>*/}    
           {/*这里模拟的是v-if的效果*/}
           {/*{!isShow || <p>我是APP组件</p>}  前面为假所以执行后面的代码*/}
          {isShow && <p>我是APP组件</p>} {/*这个与上面的相反,真的时候才走后面的代码,为假直接为假*/}
                        </div>
                    )
                }
            }
            render()
            function render(){
                ReactDOM.render(<App/>,document.getElementById("app"))
            }
class组件定义的属性

第一种写法

 class App extends React.Component{
                render(){  //render这个钩子函数必须要有
                  console.log(this)  //可以参考如下图片
                  return (   
                        <div>
                           <p>我是APP组件  ----- {this.props.name}----{this.props.age}</p>
                        </div>
                    )
                }
            } 
            render()
            function render(){
                ReactDOM.render(<App name={"张三"} age={18}/>,document.getElementById("app"))
            }

第二种写法

 let obj = {
                name:"张三",
                age:18,
                sex:"男"
            }
            
            class App extends React.Component{
                render(){  //render这个钩子函数必须要有
                  console.log(this)  
                  return (   
                        <div>
                           <p>我是APP组件  ----- {this.props.name}----{this.props.age}</p>
                        </div>
                    )
                }
            } 
            
            render()
            function render(){
                ReactDOM.render(<App {...obj}/>,document.getElementById("app"))
            }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值