react

React

官网:https://reactjs.org

React 是一个用于构建用户界面的 JavaScript 库。

特点

  • 声明式:以声明式编写 UI,可以让你的代码更加可靠,且方便调试。
  • 组件化:构建管理自身状态的封装组件,然后对其组合以构成复杂的 UI
  • 一次学习,跨平台编写:无论你现在使用什么技术栈,在无需重写现有代码的前提下,通过引入 React 来开发新功能。

react VS vue

相同点:

  • 良好的生态系统,轻量级框架
  • 虚拟DOM
  • 数据驱动视图,组件化思想

react优点:丰富的JavaScript库:来自世界各地的贡献者正在努力添加更多功能;虚拟DOM:基于文档对象模型,允许浏览器友好地以HTML,XHTML或XML格式排列文档;灵活性和响应性:它提供最大的灵活性和响应能力;可扩展性:由于其灵活的结构和可扩展性,React已被证明对大型应用程序更好;Web或移动平台: React提供React Native平台,可通过相同的React组件模型为iOS和Android开发本机呈现的应用程序

vue优点:易于使用:包含基于html的标准模板,可以更轻松的使用现有用用程序;跟顺畅的集成;更好的性能,更小的尺寸:占用更小的空间,比其他框架更好的性能;适应性:提供无障碍的迁移,简单有效的结构和可重用的模板

react脚手架

安装:

npx create-react-app my-app

注意

第一行的 npx 不是拼写错误 —— 它是 npm 5.2+ 附带的 package 运行工具。

my-app是项目名 可自定义

启动项目:

在项目根目录执行命令: npm start

目录结构介绍

Readme.md项目说明文件,先不用管它,等托管github或实际工作使用以markdown语法编写就好
package.jsonwebpack配置和项目包管理文件,里边有些命令脚本和依赖
lock文件package-lock.json或者yarn.lock都是锁定安装版本号的,保证你托管GitHub后大家下载安装的依赖是一致的
gitignoregit配置忽略文件,不需要上传的可以写里边,比如node_modules文件夹
node_module项目依赖包
public开放出去的公共资源,如果你想读取本地json,请放这个目录下
src放源码的位置,也是对我们开发者而言最核心的东西

src文件夹详解

index.js:项目的入口文件,根组件挂载根元素

输出

App.js

import React from 'react';

function App() {
  return (
    <div >
      hello world
    </div>
  );
}

export default App;

类组件和函数组件的编写

函数组件

function Header(){
  return <h1>我是头部</h1>;
}
function App() {
  return (
    <Header/>
  );
}

组件不管是定义还是使用都是大写,react中,区分组件和HTML标签的方式就是大小写。大写的以组件方式解析,小写的以HTML标签解析。

类组件

输出hello world

import React, {Component} from 'react'
class App extends Component{
    render(){
        return (
            <div>
                hello world
            </div>
        )
    }
}
export default App;

JSX使用

JSX是来描述页面的结构,我们一般在编写业务逻辑渲染页面的时候,需要涉及到传递值,调用函数,判断条件,循环等,这一些在JSX中都能得到支持

优势:

​ 1.允许使用熟悉的语法来定义 HTML 元素树;

​ 2.提供更加语义化且移动的标签;

​ 3.程序结构更容易被直观化;

​ 4.抽象了 React Element 的创建过程;

​ 5.可以随时掌控 HTML 标签以及生成这些标签的代码;

​ 6.是原生的 JavaScript。

嵌入JSX表达式

语法:{JavaScritp表达式}

<h1>{1+2}</h1>

列表渲染

  • 如果需要渲染一组数据,我们应该使用数组的 map () 方法
  • 注意:渲染列表的时候需要添加key属性,key属性的值要保证唯一
  • 原则:map()遍历谁,就给谁添加key属性
  • 注意:尽量避免使用索引号作为key
let arr = [{
    id:1,
    name:'孙悟空'
},{
    id:2,
    name:'沙悟净'
},{
    id:3,
    name:'唐僧'
},{
    id:4,
    name:'猪八戒'
}]
let ul = (<ul>
    {arr.map(item => <li key={item.id}>{item.name}</li>)}
</ul>)
ReactDOM.render(ul,document.getElementById('root'))

注意

  • 推荐使用className的方式给JSX添加样式
  • 组件名必须大写
  • 事件必须修正this指针,且绑定事件名时要使用小驼峰的写法onclick必须写成onClick
  • 如果写行内样式用双花括号{{}} <p style={{color:"red"}}>hello</p>
  • jsx语法中最外层必须有一个包裹元素,这样不行
  • 如果不想加一个额外元素,可以用Fragment官方提供的占位符

JSX使用三元运算符

  <h1>{false?"hello":"world"}</h1>

ref的作用

在这里插入图片描述

Context(解决层级出现多的情况如爷爷传递给孙子)

调用 React.createContext() 创建 Provider(提供数据) 和 Consumer(消费数据) 两个组件

const {Provider,Consumer} = React.createContext()

使用Provider组件作为组件的父节点

在这里插入图片描述

那一层想要接受父节点传来的数据用Consumer进行包裹,在里面回调函数中的参数就是传递过来的值

在这里插入图片描述

生命周期阶段(常用的钩子)

在这里插入图片描述

创建时(挂在阶段)

  • 执行时机:组件创建时(页面加载时)
  • 执行顺序

在这里插入图片描述

  • 触发时机

  • 钩子函数触发时机作用
    constructor创建组件时,最先执行1.初始化state 2.为事件处理程序绑定this
    render每次页面渲染时都会触发渲染UI(注意不能调用setState())
    componentDidMount组件挂载(完成dom渲染)后1.发网络请求 2 .DOM操作

更新时

  • 执行时机:setState() forceUpdate() ,组件接收到新的props
  • 说明以上三者任意一种变化,组件就会重新渲染
  • 执行顺序

在这里插入图片描述

钩子函数触发时机作用
render每次组件渲染都会触发渲染UI
componentDidUpdate组件更新(完成dom渲染)后1.发送网络请求2.DOM操作 注意:如果要setState()必须放在一个if条件中

卸载时

  • 执行时机:组件从页面中消失
  • 作用:用来做清理操作
钩子函数触发时机作用
componentWillUnmount组件卸载(从页面中消失)执行清理工作(比如:清理定时器等)

路由的基本使用

安装:

npm install --save react-router-dom

导入路由的三个核心组件: Router / Route / Link

import {BrowserRouter as Router, Route, Link} from 'react-router-dom'

使用Router 组件包裹整个应用

在这里插入图片描述

使用Link组件作为导航菜单(路由入口)

常用组件说明

  • Router组件:包裹整个应用,一个React应用只需要使用一次

  • 两种常用的Router: HashRouter和BrowserRouter

  • HashRouter: 使用URL的哈希值实现 (localhost:3000/#/first)

  • 推荐 BrowserRouter:使用H5的history API实现(localhost3000/first)

  • Link组件:用于指定导航链接(a标签)

  • 最终Link会编译成a标签,而to属性会被编译成 a标签的href属性

  • Route组件:指定路由展示组件相关信息

  • path属性:路由规则,这里需要跟Link组件里面to属性的值一致

  • component属性:展示的组件

  • Route写在哪,渲染出来的组件就在哪

编程式导航

  • 场景:点击登陆按钮,登陆成功后,通过代码跳转到后台首页,如何实现?
  • 编程式导航:通过JS代码来实现页面跳转
  • history是React路由提供的,用于获取浏览器历史记录的相关信息
  • push(path):跳转到某个页面,参数path表示要跳转的路径
  • go(n):前进或后退功能,参数n表示前进或后退页面数量
const Second = (props) => {
function gotoPage () {
props.history.push('/first')
}
return (<div>
<p>页面二</p>
<button onClick={gotoPage.bind(this)}>First</button>
</div>
)
}

精准匹配

  • 给Route组件添加exact属性,让其变为精准匹配模式

  • 精确匹配:只有当path和pathname完全匹配时才会展示改路由

组件性能优化

避免不必要的重新渲染

  • 组件更新机制:父组件更新会引起子组件也被更新
  • 问题:子组件没有任何变化值也会重新渲染
  • 解决方法:使用钩子函数 shouldComponentUpdate(nextProps, nextState)
  • 这个函数中nextProps和nextState是最新的状态以及属性
  • 作用:这个函数有返回值,如果返回true,代表需要重新渲染,如果返回false,代表不需要重新渲染
  • 触发时机:更新阶段的钩子函数,组件重新渲染执行((shouldComponentUpdate => render)

在这里插入图片描述

纯组件

作用以及使用

  • 纯组件: PureComponent 与 React.Component 功能相似
  • 区别: PureComponent 内部自动实现了 shouldComponentUpdate钩子,不需要手动比较
  • 原理:纯组件内部通过分别比对前两次 props 和state的值。来决定知否重新渲染组件

组件复用

使用步骤

  • 创建Mouse组件,在组建中提供复用的逻辑代码
  • 将要复用的状态作为 props.render(state)方法的参数,暴露到组件外部
  • 使用props.render() 的返回值作为要渲染的内容

在这里插入图片描述

class Mouse extends React.Component {
  // 鼠标位置状态
  state = {
    x: 0,
    y: 0
  }
  // 监听鼠标移动事件
  componentDidMount () {
    window.addEventListener('mousemove', this.handleMouseMove)
  }
  handleMouseMove = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }
  render () {
    // 向外界提供当前子组件里面的数据
    return this.props.render(this.state)
  }
}
class App extends React.Component {
  render () {
    return (
      <div>
        App
        <Mouse render={mouse => {
          return <p>X{mouse.x}</p>
        }} />
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('root'))

Children方法代替

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
class Mouse extends Component {
  // 鼠标位置状态
  state = {
    x: 0,
    y: 0
  }
  // 监听鼠标移动事件
  componentDidMount () {
    window.addEventListener('mousemove', this.handleMouseMove)
  }
  handleMouseMove = e => {
    this.setState({
      x: e.clientX,
      y: e.clientY
    })
  }
  render () {
    // 向外界提供当前子组件里面的数据
    return this.props.children(this.state)
  }
}
class App extends Component {
  render () {
    return (
      <div>
        <h1>鼠标移动</h1>
        <Mouse >
          {({ x, y }) => <p>鼠标位置:{y}</p>}
        </Mouse>
      </div>
    )
  }
}
ReactDOM.render(<App />, document.getElementById('root'))

总结:

  • render-props 是通过为组件添加 render 属性的方式传递一个函数给子组件,供子组件调用
  • children,可以实现 render-props 的功能,区别是将函数通过子组件的内容传递过来,但是 chlldren 更加强大,可以传递任意的数据给子组件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值