React学习笔记

React三大体系

1.React.js 用于web开发和组件的编写
2.ReactNative 用于移动端开发
3.ReactVR 用于虚拟现实技术的开发

React脚手架安装

  npm install -g create-react-app

创建React项目

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

项目根目录中的文件

先从进入项目根目录说起,也就是第一眼看到的文件(版本不同,可能稍有不同)

  • README.md :这个文件主要作用就是对项目的说明,已经默认写好了一些东西,你可以简单看看。如果是工作中,你可以把文件中的内容删除,自己来写这个文件,编写这个文件可以使用Markdown的语法来编写。

  • package.json: 这个文件是webpack配置和项目包管理文件,项目中依赖的第三方包(包的版本)和一些常用命令配置都在这个里边进行配置,当然脚手架已经为我们配置了一些了,目前位置,我们不需要改动。如果你对webpack了解,对这个一定也很熟悉。

  • package-lock.json:这个文件用一句话来解释,就是锁定安装时的版本号,并且需要上传到git,以保证其他人再npm install 时大家的依赖能保证一致。

  • gitignore : 这个是git的选择性上传的配置文件,比如一会要介绍的node_modules文件夹,就需要配置不上传。

  • node_modules :这个文件夹就是我们项目的依赖包,到目前位置,脚手架已经都给我们下载好了,你不需要单独安装什么。

  • public :公共文件,里边有公用模板和图标等一些东西。

  • src : 主要代码编写文件,这个文件夹里的文件对我们来说最重要,都需要我们掌握。

public文件夹介绍

这个文件都是一些项目使用的公共文件,也就是说都是共用的,我们就具体看一下有那些文件吧。

  • favicon.ico : 这个是网站或者说项目的图标,一般在浏览器标签页的左上角显示。

  • index.html : 首页的模板文件,我们可以试着改动一下,就能看到结果。

  • mainifest.json:移动端配置文件,这个会在以后的课程中详细讲解。

src文件夹介绍

这个目录里边放的是我们开放的源代码,我们平时操作做最多的目录。

  • index.js : 这个就是项目的入口文件,视频中我们会简单的看一下这个文件。

  • index.css :这个是index.js里的CSS文件。

  • app.js : 这个文件相当于一个方法模块,也是一个简单的模块化编程。

  • serviceWorker.js: 这个是用于写移动端开发的,PWA必须用到这个文件,有了这个文件,就相当于有了离线浏览的功能。

入口文件的编写

在src目录下面 新建文件夹index.js
写入下面4行代码

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />,document.getElementById('root'))

上面的代码,我们先引入了React两个必要的文件,然后引入了一个APP组件,目前这个组件还是没有的,需要一会建立。然后用React的语法把APP模块渲染到了root ID上面.这个rootID是在public\index.html文件中的。

app组件的编写

import React,{Component} form 'react'

class App extends Component{
    render(){
        return (
            <div>
                Hello JSPang
            </div>
        )
    }
}
export default App;

import React, {Component} from 'react'
可以写成
import React from 'react'
const Component = React.Component

JSX简介

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

<ul className="my-list">
 <li>JSPang.com</li>
 <li>I love React</li>
</ul>

比如我们以前写一段代码JS代码:

var child1 = React.createElement('li', null, 'JSPang.com');
var child2 = React.createElement('li', null, 'I love React');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);

组件和普通JSX语法区别

这个说起来也只有简单的一句话,就是你自定义的组件必须首写字母要进行大写,而JSX是小写字母开头的。

这个也算是一个比较重要的知识点吧。

新建组件

我们新建组件的时候,只需要把入口文件index.js的<App/>组件换成我们新建的组件就可以了。

组件外层包裹原则

这是一个很重要的原则,

import React,{Component} from 'react'

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

比如上面的代码,我们去掉最外层的div就会报错,因为React要求必须在一个组件的最外层进行包裹。

Fragment标签讲解

加上最外层的DIV,组件就是完全正确的,但是你的布局不需要最外层的标签的时候,我们就使用<Fragment>标签
要想使用<Fragment>,需要先进行引入

  import React,{Component,Fragment } from 'react'

然后把最外层的div标签换成<Fragment>标签 代码如下

import React,{Component,Fragment } from 'react'

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

这时候你再去浏览器的Elements中查看,就回发现已经没有外层的包裹了

响应式设计和数据的绑定

React不建议你直接操作DOM元素,而是要通过数据进行驱动,改变界面中的效果。React会根据数据的变化,自动的帮助你完成界面的改变。所以在写React代码时,你无需关注DOM相关的操作,只需要关注数据的操作就可以了(这也是React如此受欢迎的主要原因,大大加快了我们的开发速度)。
现在的需求是增加小姐姐的服务项,就需要先定义数据。数据定义在Xiaojiejie组件中的构造函数里constructor。

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

在 React中的数据绑定和Vue中几乎一样,也是采用字面量(我自己起的名字)的形式,就是使用{}来标注,其实这也算是js代码的一种声明。比如现在我们要把inputValue值绑定到input框中,只要写入下面的代码就可以了。其实说白了就是在JSX中使用js代码

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

绑定事件

这时候你到界面的文本框中去输入值,是没有任何变化的,这是因为我们强制绑定了inputValue的值。如果要想改变,需要绑定响应事件,改变inputValue的值。比如绑定一个改变事件,这个事件执行inputChange()(当然这个方法还没有)方法。

  <input value={this.state.inputValue} onChange={this.inputChange} />
事件的绑定需要重新定义this的指向
react改变值需要使用this.setState方法

更改上面的代码如下

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

这步做完,我们还需要加入setState方法,改变值。代码如下:

inputChange(e){
    // console.log(e.target.value);
    // this.state.inputValue=e.target.value;
    this.setState({
        inputValue:e.target.value
    })
}

列表数据化

现在的列表还是写死的两个<li>标签,那要变成动态显示的,就需要把这个列表先进行数据化,然后再用javascript代码,循环在页面上。

我们先给上节课的list数组增加两个数组元素,代码如下:

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

有了数据后,可以在JSX部分进行循环输出,代码如下:

render(){
   return  (
       <Fragment>
           <div>
               <input value={this.state.inputValue} onChange={this.inputChange.bind(this)} />
               <button> 增加服务 </button>
           </div>
           <ul>
               {
                   this.state.list.map((item,index)=>{
                       return <li>{item}</li>
                   })
               }
           </ul>  
       </Fragment>
   )
}
//循环数据的写法
{
 this.state.list.map((item,index)=>{
   return <li>{item}</li>
 })
}

扩展运算符 ... 三个点

  list:[...this.state.list,this.state.inputValue]

这里需要说的市...这个是ES6的新语法,叫做扩展运算符。意思就是把list数组进行了分解,形成了新的数组,然后再进行组合。这种写法更简单和直观,所以推荐这种写法。

循环的时候我们需要绑定key值

在需要循环的标签上面加上key={index+item}
加上item的意思是防止index的重复

数组下标的传递

如果要删除一个东西,就要得到数组里的一个编号,这里指下标。传递下标就要有事件产生,先来绑定一个双击事件.代码如下:

  onclick={this.deleteItem.bind(this,indx)}
  deleteItem(index){
         console.log(index)
  }

正式删除数据

获得了数据下标后,删除数据就变的容易起来.先声明一个局部变量,然后利用传递过来的下标,删除数组中的值.删除后用setState更新数据就可以了.

//删除单项服务
deleteItem(index){
    let list = this.state.list
    list.splice(index,1)
    this.setState({
        list:list
    })
    
}

其实这里边是有一个坑的,有的小伙伴肯定会认为下面的代码也是正确的.

deleteItem(index){
    this.state.list.splice(index,1)
    this.setState({
        list:this.state.list
    }) 
}

记住React是禁止直接操作state的,虽然上面的方法也管用,但是在后期的性能优化上会有很多麻烦,所以一定不要这样操作.这也算是我React初期踩的比较深的一个坑,希望小伙伴们可以跳坑

JSX中的class陷阱

在src目录下面写上style.css
然后在页面中引入 import './style.css'

在页面中加入类名中要写className而不是class

引入子组件

引入子组件的时候只需要

  import XiaojijieItem from './XiaojiejiItem'
  然后在页面中写入
  <XiaojiejieItem/>

父组件向子组件传值

这里只介绍最实用的,最快速的上手方法。就是使用组件属性的形式父组件给子组件传值。比如:我们在<XiaojiejieItem>组件中加入content属性,然后给属性传递{item},这样就完成了父组件向子组件传值。

  <XiaojiejieItem content={item} />

现在值已经顺利的传递了过去,这时候可以通过this.props.xxx的形式进行接受,比如传递过来的值,可以用如下代码进行接收。

import React, { Component } from 'react'; //imrc
class XiaojiejieItem  extends Component { //cc
   
    render() { 
        return ( 
            <div>{this.props.content}</div>
         );
    }
}
 
export default XiaojiejieItem;
父组件向子组件传递内容,靠属性的形式传递

子组件向父组件传递数据

React有明确规定,子组件时不能操作父组件里的数据的,所以需要借助一个父组件的方法,来修改父组件的内容。

这里我们说一下this的指向 绑定
我们可以在constructor里面提前绑定this

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

子组件调用父组件的方法
将富组件的方法用属性的方法传递
然后在子组件里面操作

<ul>
    {
        this.state.list.map((item,index)=>{
            return (
                <XiaojiejieItem 
                key={index+item}  
                content={item}
                index={index}
                //关键代码-------------------start
                deleteItem={this.deleteItem.bind(this)}
                //关键代码-------------------end
                />
            )
        })
    }
</ul>  

传递后直接在子组件里面使用

handleClick(){
   this.props.deleteItem(this.props.index)
}

本文章纯属学习笔记

引用于技术胖网站文章,如有出入请看原文
www.jspang.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335