React基础

React基础

在这里插入图片描述

React.js是全球最火的前端框架(Facebook推出的前端框架),衍生出了reactnative(移动端),reactAR(虚拟现实)。

安装nodejs好,再安装脚手架create-react-app,官方推出的。

npm install -g create-react-app

再用脚手架创建一个demo

D:  //进入D盘
mkdir ReactDemo  //创建ReactDemo文件夹
create-react-app demo01   //用脚手架创建React项目
cd demo01   //等创建完成后,进入项目目录
npm start   //预览项目,如果能正常打开,说明项目创建成功

进入项目根目录后(就是第一眼看到的目录)

  • src : 主要代码编写文件,这个文件夹里的文件对我们来说最重要。
  • node_modules :这个文件夹就是我们项目的依赖包,脚手架已经都给我们下载好了,你不需要单独安装什么。
  • gitignore : 这个是git的选择性上传的配置文件,比如node_modules文件夹,就需要配置不上传。
  • package.json: 这个文件是webpack配置和项目包管理文件,项目中依赖的第三方包(包的版本)和一些常用命令配置都在这个里边进行配置。
  • package-lock.json:这个文件用一句话来解释,就是锁定安装时的版本号,并且需要上传到git,以保证其他人再npm install 时大家的依赖能保证一致。
  • README.md :这个文件主要作用就是对项目的说明,已经默认写好了一些东西,编写这个文件可以使用Markdown的语法来编写。

src文件夹简介:

  • index.js : 这个就是项目的入口文件。
  • index.css :这个是index.js里的CSS文件。
  • app.js : 这个文件相当于一个方法模块。
  • serviceWorker.js: 这个是用于写移动端开发的,PWA必须用到这个文件,有了这个文件,就相当于有了离线浏览的功能。

入口文件的编写:

src目录下,新建一个文件index.js,然后编写最简单的代码。

import React from 'react'  //一二行是必须要引入的
import ReactDOM from 'react-dom'  //DOM(DOM—Document Object Model)是W3C国际组织的一套Web标准。DOM的本质是建立网页与脚本语言或程序语言沟通的桥梁。也叫浏览器对象,是一个分层结构。

import App from './App'   //在引入app组件,现在还没写
ReactDOM.render(<App />,document.getElementById('root'))  //APP组件渲染到了root ID上面,rootid在public/index.html

写app组件:

import React, {Component} from 'react'   //安插件Simple React Snippets,快捷键imrc

class App extends Component{
    render(){
        return (
            <div>
                Hello JSPang
            </div>
        )
    }
}
export default App;    //暴露出组件

npm start 启动,可以查看一下效果。

JSX简介:

JSX就是Javascript和XML结合的一种格式。React发明了JSX,可以方便的利用HTML语法来创建虚拟DOM,当遇到<,JSX就当作HTML解析,遇到{就当JavaScript解析.大量了简化工作。

component与JSX的区别:

自定义的组件必须首字母大写,jsx是小写字母开始。

使用自己定义的组件:把入口文件的<App />组件换成自己组件名字。

现在新建一个Xiaomeimei.js文件,打出如下代码:简单的列表。

import React,{Component} from 'react'

class Xiaomeimei extends Component{
    render(){
        return  (
            <div>
               <div><input /> <button> 增加服务 </button></div>
               <ul>
                   <li>头部按摩</li>
                   <li>精油推背</li>
               </ul> 
            </div>
        )
    }
}
export default Xiaomeimei

组件外层包裹原则:写一个组件的时候,组件的最外层都需要有一个包裹

若在布局中,真的用不上最外层的标签怎么办,没关系,react已经考虑到这个问题,用,去浏览器中看,发现没有了最外层的包裹。

响应式设计和数据绑定:
无需直接操作dom元素,只需要关注数据的操作就可以了,数据驱动(这也是React如此受欢迎的主要原因,大大加快了我们的开发速度)。

数据定义在组件的构造函数中即可

//js的构造函数,由于其他任何函数执行
constructor(props){
    super(props) //调用父类的构造函数,固定写法
    this.state={
        inputValue:'' , // input中的值
        list:[]    //服务列表
    }
}

数据绑定到输入框:但这样会把数据绑死。

<input value={this.state.inputValue} />

如果想要改变,需要绑定响应事件

<input value={this.state.inputValue} onChange={this.inputChange} />

绑定个inputChange()

inputChange(e){
    // console.log(e.target.value);
    // this.state.inputValue=e.target.value;
    this.setState({
        inputValue:e.target.value
    })   //只能用这个setstate来改变值,直接赋值是错的。
}

列表在页面上循环输出:map循环函数,里面的箭头函数带两个参数item,index。关于箭头函数,这是es6语法新增的一种新的函数,因为长得像箭头,所以叫箭头函数,相当于匿名函数。这里为了按照react的要求,我们在每个循环的li元素里,再加上key值,通常是item+index(一个index也行)。

            <ul>
                {
                    this.state.list.map((item,index)=>{
                        return <li key={index+item}>{item}</li>
                    })
                }
            </ul>

当然数据还是绑死在构造函数里面:添一个列表。

constructor(props){
    super(props) //调用父类的构造函数,固定写法
    this.state={
        inputValue:'jspang' , // input中的值
        //----------主要 代码--------start
        list:['基础按摩','精油推背']   
        //----------主要 代码--------end
    }
}

增加添加服务功能:在按钮上绑定一个this.addList()方法。

<button onClick={this.addList.bind(this)}> 增加服务 </button>

补充响应的方法:这里的三个点,是扩展运算符,也是es6的新语法,用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中,有点展开数组的意思,当然还有其他用法,这里就不展开,以后有机会写到这块儿时再展开。

//增加服务的按钮响应方法
addList(){
    this.setState({
        list:[...this.state.list,this.state.inputValue]
    })  //之前的内容循环拷贝,加上输入的内容,得到想要的。

}

增加删除功能:首先要得到要删的东西的下标,然后添加删除方法,若用纯js代码,确实需要点技术,我现在说实话是没学过js的,我是直接上手的react。此外,现在的typescript有取代js的趋势,所以我学的话是会“双管齐下”的。


说到这里,我就忍不住想补充点我的学习心得:

这个特殊的寒假,我会好好肝博客的,说点题外话,这个假期是我自学的第二个假期,第一个是大一下的暑假,现在是大二上的寒假。这个寒假因为武汉肺炎事件,寒假过成了暑假,在家自学前端,javaspringboot等。比起第一个假期,这个假期显然是学的东西更充实,大一下的暑假自学了Python,当时是在中国大学mooc上找的课,学了一段时间,后来在新生群里闲逛的时候,看到了一个学长提到淘宝上可以买教程来学,于是当晚便找到了了心仪的教程,立刻买下,下完客服让下的资源,就开始兴致勃勃的看,当时看的挺爽的,感觉学了很多不管是基础还是简单的骚操作,对我来说,开启了一个新世界。随后开始刷这些培训班的教程,也加了交流群。后来在群里了,我又发现了一座新大陆,就是大名鼎鼎的blibli,b站,当时是一位管理员提到了一位b站的up主的视频,于是我去搜,发现,哎呦,这个up主讲的东西很多啊,还很有体系。当时就想能不能在b站上找到更多类似的教程,结果让我喜出望外,果然是有的,天哪而且还免费,天哪,真香,于是我的**“面向b站编程之路”**便开始了。也不是说我当时不知道b站这个东西,其实早就知道的,但我一直以为这是看动漫的一个视频播放器而已,还没发现有学习的奇效。也理解了为什么许多人叫b站为当代大学生学习平台。嘿嘿,围绕b站的学习资源也是多的让我头大,不仅学到知识和技巧,也学到了不少巨佬的学习经验。


//删除单项服务
deleteItem(index){
    let list = this.state.list   //这里有个坑,react是禁止直接操作state的,要另外在赋到一个变量上,然后再进行处理。
    list.splice(index,1)
    this.setState({
        list:list
    })

}

注释方面用快捷键:ctrl+/,因为代码这个东西也是很有讲究的。

要自定义类的话,推荐用classname,怕和js的class重名。

jsx中HTML的解析问题,文本框里输入HTML代码,并不会被解析,只会原样打印出,这里用dangerouslysetinnerhtml属性解决,如下。

<ul>
    {
        this.state.list.map((item,index)=>{
            return (
                <li 
                    key={index+item}
                    onClick={this.deleteItem.bind(this,index)}
                    dangerouslySetInnerHTML={{__html:item}}
                >
                </li>
            )
        })
    }
</ul>

label标签:原思想label里直接for,这里也是怕和js的for循环搞在一起,用htmlfor,这样点击标签就可以输入了。

<div>
    <label htmlFor="jspang">加入服务:</label>
    <input id="jspang" className="input" value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
    <button onClick={this.addList.bind(this)}> 增加服务 </button>
</div>

父对子组件传值:通过属性传值,子组件用this.props.xxx来接收(全局参数接收)**

传递值是需要加类型限制的,不然大型项目会崩,在报错时也可以快速找出错误。通过import PropTypes from ‘prop-types’导入,在子组件中编写类型限制。使用isRequired关键字了,它表示必须进行传递该属性值。

XiaojiejieItem.propTypes={
    content:PropTypes.string,
    deleteItem:PropTypes.func,
    index:PropTypes.number
}

子对父组件传值:比如说删除功能,子组件绑定方法handleclick(),通过this.props调用父组件方法,同样用this.props调用父组件的参数。

子组件构造函数中,绑定方法,在开发高级组件时性能会高很多。

   constructor(props){
       super(props)
       this.handleClick=this.handleClick.bind(this)
   }
handleClick(){
    this.props.deleteItem(this.props.index)
}

函数式编程:

  1. 函数式编程让我们的代码更清晰,每个功能都是一个函数。
  2. 函数式编程为我们的代码测试代理了极大的方便,更容易实现前端自动化测试

单向数据流:

React developer tools:调试工具,`有三种颜色,三种颜色代表三种状态:

灰色:不是用react编写的;

红色:是react编写,处于调试环境;

黑色:是react编写的,处于生产环境;

打开浏览器,然后按F12,打开开发者工具,然后在面板的最后一个,你会返现一个React,这个就是安装的插件了。

代码语义化:增加代码可读性,就算重要成员离开,也不会导致整个项目的卡死。ref是个不错的选择。

这里面的e.target.value我看不懂很不爽

inputChange(e){

    this.setState({
        inputValue:e.target.value
    })
}

然后,这ref就出来

<input 
    id="jspang" 
    className="input" 
    value={this.state.inputValue} 
    onChange={this.inputChange.bind(this)}
    //关键代码——----------start
    ref={(input)=>{this.input=input}}
    //关键代码------------end
    />

最终效果

inputChange(){
    this.setState({
        inputValue:this.input.value
    })
}

这样就知道是thisinput的值传递过来的。

ref的一个坑:

 addList(){
    this.setState({
        list:[...this.state.list,this.state.inputValue],
        inputValue:''
    })
    //关键代码--------------start
    console.log(this.ul.querySelectorAll('div').length)
    //关键代码--------------end

}

这样写的目的是求一个无序列表的长度,但打印出来的数量却总是少一个,因为setstate是一个异步函数,虽写在关键代码的前面,但是却是后执行。每次都是先打印在添加项目。

但天无绝人之路,把关键代码放入setstate中即可,第二个函数为回调函数

addList(){
    this.setState({
        list:[...this.state.list,this.state.inputValue],
        inputValue:''
        //关键代码--------------start
    },()=>{
        console.log(this.ul.querySelectorAll('div').length)
    })
    //关键代码--------------end
}

生命周期函数:就是设计代码的人,自定义了一些有固定使用顺序的一些函数。

分四个阶段:初始化;挂载;更新;不挂载(销毁)。注意构造函数不算生命周期函数,但心里可以当做一个初始化的生命周期函数。

挂载:

  • componentWillMount : 在组件即将被挂载到页面的时刻执行。
  • render : 页面state或props发生变化时执行。
  • componentDidMount : 组件挂载完成时被执行。

更新:

shouldComponentUpdate():返回ture才能进行他后面的钩子函数。在性能优化方面,也有大作用。减少dom渲染次数。只有当内容变化时,才进行渲染。

  • nextProps:变化后的属性;
  • nextState:变化后的状态;
shouldComponentUpdate(nextProps,nextState){
    if(nextProps.content !== this.props.content){
        return true
    }else{
        return false
    }

}

还有两个,一个是组件更新前且接到shouldcomponentupdate()返回true才能执行;一个是组件更新后。

componentWillReceiveProps():子组件接收父组件props时触发。

销毁:componentWillUnmount()当组件从页面消失时执行。

Axios:ajax框架集成的远程请求数据的模块。强烈推荐组件挂载后使用axios请求远程数据。

componentDidMount(){
    axios.post('https://web-api.juejin.im/v3/web/wbbr/bgeda')
        .then((res)=>{console.log('axios 获取数据成功:'+JSON.stringify(res))  })
        .catch((error)=>{console.log('axios 获取数据失败'+error)})
}

三元表达式实现简单动画:

一个按钮控制一段文字的出现和消失;

按钮:

<div><button onClick={this.toToggole}>召唤Boss</button></div

文字:

<div className={this.state.isShow ? 'show' : 'hide'}>BOSS级人物-孙悟空</div>

转换功能:通过点击按钮,控制isshow值的真假变换

toToggole(){
    this.setState({
        isShow:this.state.isShow ? false : true
    })
}

真的话一个样式,假的话一个样式;

.show{ opacity: 1; transition:all 1.5s ease-in;}
.hide{opacity: 0; transition:all 1.5s ease-in;}

当然,isshow要设置一个初始值,方法要绑定在构造器中,这样能提高效率;

constructor(props) {
    super(props);
    this.state = { 
        isShow:true
    }
    this.toToggole = this.toToggole.bind(this);
}

当然,使用关键帧能更细致的来调节样式动画。大概就是下面的那个方式。

@keyframes hide-item{
    0% {
        opacity:1;
        color:yellow;
    }
    50%{
        opacity: 0.5 ;
        color:red;
    }
    100%{
        opacity:0;
        color: green;
    }
}

react官方也提供了一些动画组件库:react-transition-group动画组件,有完善的API。这里不做深入,想研究可以读读文档或书,来深入了解。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值