React进阶就靠这个了

React简介

(1)用来构建UI的 JavaScript库
(2)React 不是一个 MVC 框架,仅仅是视图(V)层的库
核心概念:

  1. 虚拟DOM(Virtual DOM)
  2. Diff算法(虚拟DOM的加速器,提升React性能的法宝)

React官网
React中文文档

特点

  1. 使用 JSX语法 创建组件,实现组件化开发,为函数式的 UI 编程方式打开了大门
  2. 性能高的让人称赞:通过 diff算法 和 虚拟DOM 实现视图的高效更新
  3. 使用组件化开发方式,符合现代Web开发的趋势
  4. 技术成熟,社区完善,配件齐全,适用于大型Web项目(生态系统健全)
  5. 由Facebook专门的团队维护,技术支持可靠
  6. ReactNative - Learn once, write anywhere: Build mobile apps with React
  7. 使用方式简单,性能非常高,支持服务端渲染
  8. 有利于参与潜力大的项目

key 属性

React提供了一个 key 属性。当子节点带有key属性,React会通过key来匹配原始树和后来的树。

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

// 新
<ul>
  <li key="2017">Connecticut</li>
  <li key="2018">Duke</li>
  <li key="2019">Villanova</li>
</ul>

执行过程:
现在 React 知道带有key ‘2017’ 的元素是新的,对于 ‘2018’ 和 ‘2019’ 仅仅移动位置即可

说明:key属性在React内部使用,但不会传递给你的组件
推荐:在遍历数据时,推荐在组件中使用 key 属性:

<li key={item.id}>{item.name}</li>

注意:key只需要保持与他的兄弟节点唯一即可,不需要全局唯一
注意:尽可能的减少数组index作为key,数组中插入元素的等操作时,会使得效率底下

React的基本使用

  1. 安装:npm i -S react react-dom
  2. react:react 是React库的入口点
  3. react-dom:提供了针对DOM的方法,比如:把创建的虚拟DOM,渲染到页面上
// 1. 导入 react
import React from 'react'
import ReactDOM from 'react-dom'

// 2. 创建 虚拟DOM
// 参数1:元素名称  参数2:元素属性对象(null表示无)  参数3:当前元素的子元素string||createElement() 的返回值
const divVD = React.createElement('div', {
  title: 'hello react'
}, 'Hello React!!!')

// 3. 渲染
// 参数1:虚拟dom对象  参数2:dom对象表示渲染到哪个元素内 参数3:回调函数
ReactDOM.render(divVD, document.getElementById('app'))

createElement()的问题

说明:createElement()方式,代码编写不友好,太复杂

var dv = React.createElement(
  "div",
  { className: "shopping-list" },
  React.createElement(
    "h1",
    null,
    "Shopping List for "
  ),
  React.createElement(
    "ul",
    null,
    React.createElement(
      "li",
      null,
      "Instagram"
    ),
    React.createElement(
      "li",
      null,
      "WhatsApp"
    )
  )
)
// 渲染
ReactDOM.render(dv, document.getElementById('app'))

JSX 的基本使用

  1. 注意:JSX语法,最终会被编译为 createElement() 方法
  2. 推荐:使用 JSX 的方式创建组件
  3. JSX - JavaScript XML
  4. 安装:npm i -D babel-preset-react (依赖与:babel-core/babel-loader)

注意:JSX的语法需要通过 babel-preset-react 编译后,才能被解析执行

/* 1 在 .babelrc 开启babel对 JSX 的转换 */
{
  "presets": [
    "env", "react"
  ]
}

/* 2 webpack.config.js */
module: [
  rules: [
    { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ },
  ]
]

/* 3 在 js 文件中 使用 JSX */
const dv = (
  <div title="标题" className="cls container">Hello JSX!</div>
)

/* 4 渲染 JSX 到页面中 */
ReactDOM.render(dv, document.getElementById('app'))

JSX的注意点

  1. 注意 :
    如果在 JSX 中给元素添加类, 需要使用 className 代替 class
    类似:label 的 for属性,使用htmlFor代替
  2. 注意 :在 JSX 中可以直接使用 JS代码,直接在 JSX 中通过 {} 中间写 JS代码即可
  3. 注意 :在 JSX 中只能使用表达式,但是不能出现 语句!!!
  4. 注意 :在 JSX 中注释语法:{/* 中间是注释的内容 */}

React组件

组件是由一个个的HTML元素组成的
概念上来讲, 组件就像JS中的函数。它们接受用户输入(props),并且返回一个React对象,用来描述展示在页面中的内容

React创建组件的两种方式

  1. 通过 JS函数 创建(无状态组件)
  2. 通过 class 创建(有状态组件)

函数式组件 和 class 组件的使用场景说明:

  1. 如果一个组件仅仅是为了展示数据,那么此时就可以使用 函数组件
  2. 如果一个组件中有一定业务逻辑,需要操作数据,那么就需要使用 class 创建组件,因为,此时需要使用 state

JavaScript函数创建

  1. 函数名称必须为大写字母开头,React通过这个特点来判断是不是一个组件
  2. 函数必须有返回值,返回值可以是:JSX对象或null
  3. 返回的JSX,必须有一个根元素
  4. 组件的返回值使用()包裹,避免换行问题

class创建

在es6中class仅仅是一个语法糖,不是真正的类,本质上还是构造函数+原型 实现继承

给组件传递数据 - 父子组件传递数据

组件中有一个 只读的对象 叫做 props,无法给props添加属性
获取方式:函数参数 props
作用:将传递给组件的属性转化为 props 对象中的属性

function Welcome(props){
  // props ---> { username: 'zs', age: 20 }
  return (
    <div>
      <div>Welcome React</div>
      <h3>姓名:{props.username}----年龄是:{props.age}</h3>
    </div>
  )
}


// 给 Hello组件 传递 props:username 和 age(如果你想要传递numb类型是数据 就需要向下面这样)
ReactDOM.reander(<Hello username="zs" age={20}></Hello>, ......)

封装组件到独立的文件中

// 创建Hello2.js组件文件
// 1. 引入React模块
// 由于 JSX 编译后会调用 React.createElement 方法,所以在你的 JSX 代码中必须首先拿到React。
import React from 'react'

// 2. 使用function构造函数创建组件
function Hello2(props){
  return (
    <div>
      <div>这是Hello2组件</div>
      <h1>这是大大的H1标签,我大,我骄傲!!!</h1>
      <h6>这是小小的h6标签,我小,我傲娇!!!</h6>
    </div>
  )
}
// 3. 导出组件
export default Hello2

// app.js中   使用组件:
import Hello2 from './components/Hello2'

props和state

JSX语法转化过程

组件的生命周期

简单说:一个组件从开始到最后消亡所经历的各种状态,就是一个组件的生命周期
组件生命周期函数的定义:从组件被创建,到组件挂载到页面上运行,再到页面关闭组件被卸载,这三个阶段总是伴随着组件各种各样的事件,那么这些事件,统称为组件的生命周期函数!

state和setState

组件绑定事件

1 通过React事件机制 onClick 绑定
2 JS原生方式绑定(通过 ref 获取元素)

事件绑定中的this

  1. 通过 bind 绑定
  2. 通过 箭头函数 绑定

通过bind绑定

原理:bind能够调用函数,改变函数内部this的指向,并返回一个新函数
说明:bind第一个参数为返回函数中this的指向,后面的参数为传给返回函数的参数

// 自定义方法:
handleBtnClick(arg1, arg2) {
  this.setState({
    msg: '点击事件修改state的值' + arg1 + arg2
  })
}

render() {
  return (
    <div>
      <button onClick={
        // 无参数
        // this.handleBtnClick.bind(this)

        // 有参数
        this.handleBtnClick.bind(this, 'abc', [1, 2])
      }>事件中this的处理</button>
      <h1>{this.state.msg}</h1>
    </div>
  )
}

在构造函数中使用bind

constructor() {
  super()

  this.handleBtnClick = this.handleBtnClick.bind(this)
}
// render() 方法中:
<button onClick={ this.handleBtnClick }>事件中this的处理</button>

通过箭头函数绑定

原理:箭头函数中的this由所处的环境决定,自身不绑定this

<input type="button" value="在构造函数中绑定this并传参" onClick={
  () => { this.handleBtnClick('参数1', '参数2') }
} />

handleBtnClick(arg1, arg2) {
  this.setState({
    msg: '在构造函数中绑定this并传参' + arg1 + arg2
  });
}

受控组件

表单和受控组件
非受控组件

props校验

React 单向数据流

React 中采用单项数据流
单向数据流
状态提升

组件通讯

  1. 父 -> 子:props
  2. 子 -> 父:父组件通过props传递回调函数给子组件,子组件调用函数将数据作为参数传递给父组件
  3. 兄弟组件:因为React是单向数据流,因此需要借助父组件进行传递,通过父组件回调函数改变兄弟组件的props

React中的状态管理: flux(提出状态管理的思想) -> Redux -> mobx
Vue中的状态管理: Vuex

简单来说,就是统一管理了项目中所有的数据,让数据变的可控
组件通讯

Context特性

  1. 注意:如果不熟悉React中的数据流,不推荐使用这个属性
    这是一个实验性的API,在未来的React版本中可能会被更改
  2. 作用:跨级传递数据(爷爷给孙子传递数据),避免向下每层手动地传递props
  3. 说明:需要配合PropTypes类型限制来使用
class Grandfather extends React.Component {
  // 类型限制(必须),静态属性名称固定
  static childContextTypes = {
    color: PropTypes.string.isRequired
  }

  // 传递给孙子组件的数据
  getChildContext() {
    return {
      color: 'red'
    }
  }

  render() {
    return (
      <Father></Father>
    )
  }
}

class Child extends React.Component {
  // 类型限制,静态属性名字固定
  static contextTypes = {
    color: PropTypes.string
  }

  render() {
    return (
      // 从上下文对象中获取爷爷组件传递过来的数据
      <h1 style={{ color: this.context.color }}>爷爷告诉文字是红色的</h1>
    )
  }
}

class Father extends React.Component {
  render() {
    return (
      <Child></Child>
    )
  }
}

react-router

react router 官网
react router github
安装:npm i -S react-router-dom

Router组件本身只是一个容器,真正的路由要通过Route组件定义
使用步骤

  1. 导入路由组件
  2. 使用 作为根容器,包裹整个应用(JSX)
    在整个应用程序中,只需要使用一次
  3. 使用 作为链接地址,并指定to属性
  4. 使用 展示路由内容
// 1 导入组件
import {
  HashRouter as Router,
  Link, Route
} from 'react-router-dom'

// 2 使用 <Router>
<Router>

// 3 设置 Link
<Menu.Item key="1"><Link to="/">首页</Link></Menu.Item>
<Menu.Item key="2"><Link to="/movie">电影</Link></Menu.Item>
<Menu.Item key="3"><Link to="/about">关于</Link></Menu.Item>

// 4 设置 Route
// exact 表示:绝对匹配(完全匹配,只匹配:/)
<Route exact path="/" component={HomeContainer}></Route>
<Route path="/movie" component={MovieContainer}></Route>
<Route path="/about" component={AboutContainer}></Route>

</Router>

注意

  1. :作为整个组件的根元素,是路由容器,只能有一个唯一的子元素
  2. :类似于vue中的标签,to 属性指定路由地址
  3. :类似于vue中的,指定路由内容(组件)展示位置

路由参数

配置:通过Route中的path属性来配置路由参数
获取:this.props.match.params 获取

// 配置路由参数
<Route path="/movie/:movieType"></Route>

// 获取路由参数
const type = this.props.match.params.movieType

路由跳转

  1. react router - history

  2. history.push() 方法用于在JS中实现页面跳转

  3. history.go(-1) 用来实现页面的前进(1)和后退(-1)

     this.props.history.push('/movie/movieDetail/' + movieId)
    

跨域获取数据的三种常用方式

  1. JSONP
  2. 代理
  3. CORS

PropTypes类型检查

proptypes类型检查工具

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值