react笔记

鲜于凯康
2023-12-01

react

react是facebook出的一款针对view视图层的library库。react遵循单向数据流的机制。目前我们学的是react17.x的版本

React 官方中文文档 – 用于构建用户界面的 JavaScript 库

react基础语法和常见api

  • jsx语法

    就是在js种直接使用html标签来写。

    const str = '你好啊!'
    const people = [<p>苹果嘉儿</p>,<p>云宝</p>,<p>紫悦</p>,<p>珍奇</p>]
    function Demo() {
        return <>
            <h1>我是一个组件</h1>
            <p>{str}</p>
            <hr/>
            {people}
            <hr/>
            {people.length>1?'人数多于一个':'人数少于一个'}
           </>
    }

  • function定义组件

  • 组件传参

    父传子使用props

    子传父使用方法调用

  • hooks

    是react16.8之后新增得功能,可以在function定义得组件中设置局部状态和模拟组件的生命周期。是目前官方推荐的组件定义方式。

    • useState

      可以在function定义的组件中设置局部状态数据,当状态数据改变的时候组件会重新更新

      function App() {
          const [count, setCount] = React.useState(1) //
          // useState返回一个数组,接收一个参数作为初始状态数据
          // 一个组件中可以定义多次useState,但是它不能放在循环或者条件语句中
          //  第一项表示变量名
          //  第二项表示改变数据的方法
          // 当count值变了,这个function中的代码会重新执行
          ....
      }

    • useEffect

      副作用,接收两个参数

      参数一:回调函数,回调函数可以返回一个function,这个返回值在组件销毁的时候执行

      参数二:依赖数组

      当依赖数组中的数据改变的时候,回调函数会执行

      关于参数二有以下几种场景

      1. 参数二不存在,没有参数二。当组件的属性或者状态数据改变的时候,参数一的回调函数都会执行

      2. 参数二是一个空数组,就是数组没有内容。只在组件初始化的时候执行一次,用来调接口取数据

      3. 参数二是一个正常的数据。当数组中的任意一项发生了改变,那么回调函数就会执行

    • useRef

      作用是获取组件中的dom元素

    • useContext

      上下文,在react中实现跨组件之间传参.

    • useCallback

      对function做缓存,接收两个参数,参数一是一个function,参数二是一个依赖数组。当依赖数组中的数据改变的时候function会重新执行

    • useMemo

      对值做缓存,接收两个参数,参数一是一个返回一个值的function,参数二是一个依赖数组。当依赖数组中的数据改变的时候被缓存的值会重新计算

    • memo

      对组件做缓存,主要是做性能优化。当组件接收到的属性没有改变的时候组件不会重新渲染

  • class定义组件

    class定义组件时react中另外一种定义组件的方式。可以在组件内部设置局部状态和生命周期。当状态或者属性数据改变的时候组件会重新渲染

    class定义的组件和function定义的组件是可以混合使用的

    class Counter extends React.Component {
        // 每一个组件都需要有一个render方法,这个方法需要一个返回值,返回一个html节点作为当前组件展示的元素内容
        render() {
            return <h1>我是一个计数器</h1>
        }
    }

    • 组件状态

      state表示局部状态

      如果要改变状态数据,需要调用setState方法。setState方法接收两个参数,一般参数二都不用。改变state数据是异步操作的,在参数二的回调函数中可以获取state改变之后的最新数据

      ...
      this.setState({
          count: 18
      }, function() {
          // 这里可以获取state的最新数据
          console.log(this.state)
      })
      ...
    • this指向问题

      改变this指向有三种写法:

      1. 在constructor中直接绑定(建议使用第一种)

      2. 在render的时候进行绑定

      3. 使用箭头函数(如果需要传参使用第三种)

      // 在class定义的组件中有一个很麻烦的问题,就是this指向问题
      class Counter extends React.Component {
          // 创建的时候执行
          constructor(props) {
              super(props);
              // 通过this.state可以为组件设置状态数据
              this.state = {
                  count: 1,
                  name: "counter计数器",
              };
              this.clickHandle = this.clickHandle.bind(this); // 推荐写法
          }
          clickHandle() {
              // console.log(this);
              // 在class定义的组件中如果我们要改变state数据,需要调用setState方法
              //  setState是异步的,如果想获取最新的state数据,需要在参数二的回调函数中获取值
              this.setState(
                  {
                      count: this.state.count + 1,
                  },
                  function () {
                      console.group("回调函数中获取");
                      console.log(this.state.count);
                      console.groupEnd();
                  }
              );
              console.log(this.state.count);
          }
          clickHandle2() {
              this.setState({
                  count: this.state.count + 2,
              });
          }
          clickHandle3() {
              this.setState({
                  count: this.state.count + 3,
              });
          }
          // 在属性或者数据改变的时候会调用
          render() {
              console.log("render执行了");
              return (
                  <>
                  <h1>
                      {this.state.name}-{this.state.count}
                  </h1>
                  <button onClick={this.clickHandle}>加+</button>
                  <button onClick={this.clickHandle2.bind(this)}>加+2</button>
                  <button onClick={() => this.clickHandle3()}>加+3</button>
                  </>
              );
          }
      }
      const App = () => (
          <>
          <h1>我是组件</h1>
          <Counter />
          </>
      );
      ReactDOM.render(<App />, document.querySelector("#app"));

    • PureComponent

      对组件做性能优化,组件属性只做浅比较。当属性没有改变的时候组件不会重新渲染。相当于function定义组件中的memo方法

    • contextType

      通过为组件设置属性contextType可以在组件内部获取context上下文中提供的数据

      const { createContext, Component } = React;
      const context = createContext();
      class AppProvider extends Component {
          constructor(props) {
              super(props);
          }
          render() {
              return (
                  <context.Provider value={{ name: "class定义的组件" }}>
                      {this.props.children}
                  </context.Provider>
              );
          }
      }
      class Home extends Component {
          constructor(props) {
              super(props);
          }
          render() {
              console.log(this.context);
              return (
                  <>
                  <h1>首页</h1>
                  <p>{this.context.name}</p>
                  </>
              );
          }
      }
      Home.contextType = context; // 通过为组件设置一个contextType属性把context上下文中的value数据映射到组件内部
      const App = () => (
          <>
          <h1>我是组件</h1>
          <Home />
          </>
      );
      ReactDOM.render(
          <AppProvider>
              <App />
          </AppProvider>,
          document.querySelector("#app")
      );

    • 组件生命周期

      class组件的生命周期16.3之前和之后有差异

      16.3之前的钩子函数:

      • constructor(不算生命周期钩子函数,应该是class的构造函数,可以在这里面设置state数据和获取props属性)

      • componentWillMount,组件挂载之前执行

      • componentDidMount【很重要】,class定义的组件在这里获取数据

      • componentWillReceiveProps,将要接收新的属性

      • shouldComponentUpdate,组件是否需要更新。主要用来做性能优化的时候需要操作的生命周期函数。返回bool值,true后续的更新阶段会执行;否则不更新

      • componentWillUpdate,将要更新

      • componentDidUpdate,更新完成

      • componentWillUnmount,卸载

      16.3之后的删除了will开头的三个函数(componentWillMount、componentWillReceiveProps、componentWillUpdate)。新增了几个钩子函数,作为了解听过就行

      function定义的组件中useEffect对应class定义组件中的三个生命周期钩子函数:componentDidMount、componentDidUpdate、componentWillUnmount

      和function定义的组件的useEffect对应:

      // 参数二为空数组,对应componentDidMount
      useEffect(()=>{
          return () => {
              // 对应componentWillUnmount
          }
      }, [])
      // 对应componentDidUpdate
      useEffect(()=>{
          
      }, [xx])

      嵌套组件的生命周期问题:如果组件出现嵌套,那么在执行父组件的更新或者挂载完成之前会完成所有子组件的挂载和更新。最后才会执行外围的挂载和更新完成

    • class组件中使用ref

      用来获取组件中的dom元素

    • function和class定义组件的区别

      function定义的组件中不存在this指向问题,function定义的组件又叫无状态组件但是在react16.8之后新增了hooks,可以在function定义的组件中模拟局部状态和生命周期

      class定义的组件有自己的局部状态和生命周期

      目前官方推荐使用function的方式定义组件


      备注:hooks在2019年的时候已经开始推荐并普及使用,antd是react中一个非常知名的ui组件库,它在4.0之后的版本中已经开始全面使用function+hooks的写法

  • useReducer

    是react中的一个hooks,可以让我们使用类似redux中的数据流机制进行状态数据的管理

    reducer是一个function,这个function接收两个参数(state,action),返回一个新的state数据

    • state表示状态数据

    • action表示行为,必须包含一个type属性

  • 高阶组件

react脚手架

  • create-react-app

    create-react-app(CRA)是官方的脚手架,这个脚手架只提供基础的一些插件,是基于webpack的。

    npx create-react-app first-react-app # 创建一个react项目
    cd first-react-app
    npm start # 启动项目

    如果电脑上安装的有yarn这个模块管理工具,那么cra默认使用的是yarn做模块管理

    yarn

    它是facebook推出的一款包管理工具,和npm是一样的功能

    Yarn 中文文档

    npm i yarn -g # 安装yarn
    # 使用
    yarn add xx			# 安装模块
    yarn remove xx		# 删除模块
    yarn 				# 找到package.json文件,根据依赖项安装所有的依赖
  • vite

    它是另外的一种创建项目的方式,使用的不是webpack。下一代前端开发与构建工具

    Vite 官方中文文档

    npm init vite@latest
    # or
    yarn create vite

    使用sass

    npm i sass -D # 安装sass插件就行
  • 路由

    React Router: Declarative Routing for React.js

    安装

    npm i react-router-dom # 安装路由插件

    使用

    • HashRouter或者BrowserRouter

      路由组件的根节点,一个项目中只能有一个

    • Route

      路由组件,每一个路径对应显示的内容在这里标准

      • path

        表示路由的路径,就是url中访问的地址,访问指定路径的时候展示对应的组件

      • exact

        表示绝对匹配

      Route对应展示的组件有三种写法

      • 直接写成子标签children的形式

        <Route path="/list">
        	<List/>
        </Route>

        推荐用法,在List组件的属性中不能直接获取路由对象信息,但可以通过withRouter方法实现

      • 写成属性component

        <Route path="/list" component={List} />

        可以直接在List组件的属性中获取路由对象信息

      • 通过render方法展示

        <Route path="/list" render={()=><List/>} />

        在List组件的属性中不能直接获取路由对象信息,但可以通过withRouter方法实现

    • Link

      生成跳转链接

    • Switch

      只匹配一个

    • withRouter

      作用是把路由对象的属性信息映射到组件的属性上

      import React from "react";
      import { withRouter } from "react-router-dom";
      
      function Products(props) {
        console.group("products");
        console.log(props);
        console.groupEnd();
        return (
          <div>
            <h2>商品列表</h2>
          </div>
        );
      }
      
      export default withRouter(Products);
    • 路由传参

      • params

        需要在路由中设置占位符。如果没有占位符,那么刷新之后会消失

      • search

        就是直接在url中传递,通过?进行分割。刷新之后也不会消失。建议使用search

      • state

        直接传递。刷新之后直接消失

      • useLocation

        获取location数据,可以用来获取参数

      • useHistory

        获取历史记录信息,可以使用push、go等方法做跳转

      • useParams

        获取parmas参数

  • antd

    ant.design是蚂蚁金服出的一款ui组件库。

    Ant Design - 一套企业级 UI 设计语言和 React 组件库

    npm i antd # 安装依赖

  • 管理后台项目

  • redux

    Redux - A predictable state container for JavaScript apps. | Redux

    redux是一个全局状态管理插件。它是单向数据流的。

    单向数据流:数据是单向流动的,分为三部分(state,action,view)。在view视图中通过dispatch派发一个action改变数据,数据改变之后view视图重新渲染

    • action

      行为,每一个action都建议有一个type属性,type不能重复。因为在dispatch派发的时候所有的reducer都会收到这个action,根据type不一样来做不同的处理

    • state

      存储数据

    • reducer

      改变数据的地方,reducer是一个function。接收两个参数

      参数一 表示state的初始值

      参数二是一个action

    • 安装使用

      npm i redux # 安装插件,是核心模块
      npm i react-redux # 插件的作用是实现redux和react的连接
    • redux中的方法

      • createStore 作用是创建一个数据存储

      • combineReducers 合并多个reducer为一个

    • react-redux中的方法

      • Provider

        是一个组件需要放在项目的最外层,用来把store数据传递给整个项目

      • connect

        实现数据以及dispatch方法和组件的关联,把数据和dispatch方法映射到组件的属性上

      • useSelector

        获取state数据

      • useDispatch

        获取dispatch方法

    • redux-thunk

      插件的作用是用来处理异步action。所有的action必须返回一个plain object,不能是一个function。为了解决异步问题,可以借助插件实现

      redux-thunk,它的作用是判断action的数据类型,如果是function,那么会把dispatch当参数传递给function;如果是一个对象,那么就直接执行

    • redux-toolkits

      它目前是redux官方推荐的写法

      npm install @reduxjs/toolkit react-redux # 安装依赖

  • umi

    UmiJS - Extensible enterprise-level front-end application framework.

    umi是一个企业级的开发框架,内置了react、react-router、dva、antd等插件,可以实现开箱即用

    • dva

      是一个redux的封装,内置了常见的redux插件:redux-thunk、redux-saga、redux-devtools等等,可以让我们很方便的来实现redux的使用

  • ts和antd pro

  • 其他ui框架

  • next.js

    它是一个react的服务器端渲染框架,可以做多页面应用程序开发。解决了单页面应用程序存在的所有弊端。

    npx create-next-app first-next-app-pre # 创建一个next项目

 类似资料: