react学习

Posted 暑假过期le

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了react学习相关的知识,希望对你有一定的参考价值。

React

React的特点

1.采用组件化模式,声明式编码,提高开发效率及组件复用率

2.在React Native中可以使用React语法进行移动端开发

3.使用虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互

虚拟DOM和真实DOM的差别

虚拟dom:

1.本质式object类型的对象(一般对象)

2.虚拟dom比较‘轻’,真实dom比较‘重’,因为虚拟dom是react内部使用,无需真实dom这么个那么多的属性

3.虚拟dom最终会被react转化为dom,呈现在页面上

扩展:debugger 断点

jsx语法规则

jsx语法规则:

1.定义虚拟dom的时候,不用写引号
在这里插入图片描述

2.标签中混入js表达式的时候用{}

在这里插入图片描述

3.样式的类名指定不要用class,要用className

4.内联样式,要用style={{key:value}}的形式去写

在这里插入图片描述

5.只有一个根标签

6.标签必须闭合 单标签可以写成

7.标签首字母

  1. 如果小写字母开头,则将该标签转为html中的同名元素,如果html标签中没有同名元素报错
  2. 如果大写字母开头,react就去渲染对用的组件,如果没有定义组件,报错

区分 js语句(代码)与js表达式

表达式:一个表达式会产生一个值,可以放在任何一个需要的地方

  1. a
  2. a+b
  3. six(1)
  4. arr.map()
  5. function text(){}

语句(代码)

  1. if{}
  2. for{}
  3. switch(){case:…}

在这里插入图片描述

函数式组件写法

在这里插入图片描述

类式组件写法

在这里插入图片描述

复杂组件和简单组件

简单组件是没有状态的

复杂组件是有状态的

在这里插入图片描述

ref的作用

在这里插入图片描述

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

使用步骤

  • 调用 React.createContext() 创建 Provider(提供数据) 和 Consumer(消费数据) 两个组件
const {Provider,Consumer} = React.createContext()

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

在这里插入图片描述

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

在这里插入图片描述

props校验

在这里插入图片描述

常见的约束规则

  • 创建的类型: array、bool、func、number、object、string

  • React元素类型: element

  • 必填项: isRequired

  • 特定结构的对象: shape({})

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

在这里插入图片描述

创建时(挂在阶段)

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

  • 执行顺序

在这里插入图片描述

  • 触发时机

  • 钩子函数触发时机作用
    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组件卸载(从页面中消失)执行清理工作(比如:清理定时器等)

Diff算法

执行过程

  • 初次渲染时,React会根据初始化的state(model),创建一个虚拟dom的对象(树)
  • 根据虚拟DOM生成真正的DOM,渲染到页面
  • 当数据变化后(setState()),会重新根据新的数据,创建新的虚拟DOM对象(树)
  • 与上一次得到的虚拟DOM对象,使用Diff算法比对(找不同),得到需要更新的内容
  • 最终,React只将变化的内容更新(patch)到DOM中,重新渲染到页面

在这里插入图片描述

路由的基本使用

安装:

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 更加强大,可以传递任意的数据给子组件

高阶组件(HOC)

使用步骤

  • 创建一个函数,名称约定以with开头
  • 指定函数参数,参数应该以大写字母开头
  • 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
  • 在该组件中,渲染参数组件,同时将状态通过prop传递给参数组件
  • 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面

包装函数

// 定义一个函数,在函数内部创建一个相应类组件
function withMouse (WrappedComponent) {
  // 该组件提供复用状态逻辑
  class Mouse extends React.Component {
    state = {
      x: 0,
      y: 0
    }
    // 事件的处理函数
    handleMouseMove = (e) => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }
    // 当组件挂载的时候进行事件绑定
    componentDidMount () {
      window.addEventListener('mousemove', this.handleMouseMove)
    }
    // 当组件移除时候解绑事件
    componentWillUnmount () {
      window.removeEventListener('mousemove', this.handleMouseMove)
    }
    render () {
      // 在render函数里面返回传递过来的组件,把当前组件的状态设置进去
      return <WrappedComponent {...this.state} />
    }
  }
  return Mouse
}

哪个组件需要加强,通过调用 withMouse 这个函数,然后把返回的值设置到父组件中即可

function Position (props) {
  return (
    <p>
      X:{props.x}
  Y:{props.y}
    </p>
  )
}
// 把position 组件来进行包装
let MousePosition = withMouse(Position)
class App extends React.Component {
  constructor(props) {
    super(props)
  }
  render () {
    return (
      <div>
        高阶组件
        <MousePosition></MousePosition>
      </div>
    )
  }
}

以上是关于react学习的主要内容,如果未能解决你的问题,请参考以下文章

javascript 用于在节点#nodejs #javascript内设置react app的代码片段

中继片段传播不起作用

前端开发工具vscode如何快速生成代码片段

前端开发工具vscode如何快速生成代码片段

[React Testing] Use Generated Data in Tests with tests-data-bot to Improve Test Maintainability(代码片段

react简介