• react从不会到入门


    1_react初识

    react教程

    1.1_react基础环境搭建

    方法一:使用npm安装react脚手架npm install -g create-react-app,然后create-react-app app-name

    方法二:直接使用react脚手架搭建项目结构npx create-react-app app-name ,其中app-name的“-”不能省略,npx是临时安装脚手架,构建完项目后会自动删除。

    1.2_文件目录介绍

    请添加图片描述

    package.json

    {
    //项目依赖目录
      "dependencies": {
        "@testing-library/jest-dom": "^5.16.5",
        "@testing-library/react": "^13.4.0",
        "@testing-library/user-event": "^13.5.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-scripts": "5.0.1",
        "web-vitals": "^2.1.4"
      },
    //命令列表
      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },
      "eslintConfig": {
        "extends": [
          "react-app",
          "react-app/jest"
        ]
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    index.js

    //React:框架的核心包
    //ReactDOM:专门做渲染相关的包
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    //引入全局的样式文件
    import './index.css'
    //项目的根组件
    import App from './App';
    //获取root元素,root元素位于public目录下index.html中
    const root = ReactDOM.createRoot(document.getElementById('root'));
    //对root进行渲染
    root.render(
        //如果是react18版本需要去掉标签
      <React.StrictMode>
        <App />
      </React.StrictMode>
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1.2_JSX基础

    1.2.1_JSX介绍

    1. 概念:JSX是JavaScript XML (HTML)的缩写,表示在JS代码中书写HTML结构

    2. 作用:在React中创建HTML结构(页面UI结构)

    3. 原理:JSX并不是标准的JS语法,是JS的语法扩展,浏览器默认是不识别的,脚手架中内置的@babel/plugin-transform-react-jsx包,用来解析该语法

    1.2.2_JSX表达式

    语法:

    {JS表达式}//将此式放入html语法中即可,注意只能是表达式不能是语句(如if等语句则报错)
    
    • 1
    const name = '佳佳'
    const flag = true
    function App() {
      return (
        <div className="App">
          {name}
          {flag?'周周':'蛇蛇'}
        </div>
      );
    }
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    请添加图片描述

    1.2.3_列表渲染

    const songs = [
      { id: 1, name: '痴心绝对' },
      { id: 2, name: '像我这样的人' },
      { id: 3, name: '南山南' }
    ]
    function App() {
      return (
        <div className="App">
          //使用map进行逐个渲染
          {songs.map(itemName => <li key={songs.id}>{itemName.name}</li>)}
          //等价于
          <li key={songs[0].id}>{songs[0].name}</li>
          <li key={songs[1].id}>{songs[1].name}</li>
          <li key={songs[2].id}>{songs[2].name}</li>
        </div>
      );
    }
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.2.4_条件渲染

    // 来个布尔值
    const flag = true
    function App() {
      return (
        <div className="App">
          {/* 条件渲染字符串 */}
          {flag ? 'react真有趣' : 'vue真有趣'}
          {/* 条件渲染标签/组件 */}
          {flag ? <span>this is span</span> : null}
        </div>
      )
    }
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.2.5_函数调用

    const fun = (type)=>{
        if (type === 1)return <h1>蛇蛇</h1>
        else return <h1>周周</h1>
    }
    function App() {
        return (
            <div className="App">
                {fun(1)}
            </div>
        );
    }
    export default App;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.2.6_样式控制

    1. 行内样式
    const styleObj = {
        color:red
    }
    function App() {
      return (
        <div className="App">
          <div style={ styleObj }>this is a div</div>
        </div>
      )
    }
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 类名样式

    创建一个css文件,然后在本文件导入即可使用css中已声明好的样式

    app.css

    .title {
      font-size: 30px;
      color: blue;
    }
    
    • 1
    • 2
    • 3
    • 4

    app.js

    import './app.css'
    function App() {
      return (
        <div className="App">
          <div className='title'>this is a div</div>
        </div>
      )
    }
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2_组件基础

    2.1_函数组件

    1. 组件的名称必须首字母大写,react内部会根据这个来判断是组件还是普通的HTML标签
    2. 函数组件必须有返回值,表示该组件的 UI 结构;如果不需要渲染任何内容,则返回 null

    2.2_点击事件

    function App() {
        //e是点击事件信息
        const onclickEvent=(e,str)=>{
            console.log(e,str)
        }
        return (
            <div className="App" onClick={(e)=>{onclickEvent(e,"蛇蛇")}}>
                点击一下
            </div>
        );
    }
    export default App;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3_组件通讯

    组件是独立且封闭的单元,默认情况下组件只能使用自己的数据(state)

    组件化开发的过程中,完整的功能会拆分多个组件,在这个过程中不可避免的需要互相传递一些数据

    为了能让各组件之间可以进行互相沟通,数据传递,这个过程就是组件通信

    1. 父子关系 - 最重要的
    2. 兄弟关系 - 自定义事件模式产生技术方法 eventBus / 通过共同的父组件通信
    3. 其它关系 - mobx / redux / zustand

    3.1_父子关系

    父传子:

    1. props是只读对象(readonly)

    根据单项数据流的要求,子组件只能读取props中的数据,不能进行修改

    2. props可以传递任意数据

    数字、字符串、布尔值、数组、对象、函数、JSX

    import React from 'react'
    
    // 函数式子组件
    function FSon(props) {
      console.log(props)
      return (
        <div>
          子组件1
          {props.msg}
        </div>
      )
    }
    // 父组件
    class App extends React.Component {
      state = {
        message: 'this is message'
      }
      render() {
        return (
          <div>
            <div>父组件</div>
            <FSon msg={this.state.message} />
          </div>
        )
      }
    }
    
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    子传父:

    子组件调用父组件的函数进行传值;

    import React from 'react'
    
    // 子组件
    function Son(props) {
      function handleClick() {
        // 调用父组件传递过来的回调函数 并注入参数
        props.changeMsg('this is newMessage')
      }
      return (
        <div>
          <button onClick={handleClick}>change</button>
        </div>
      )
    }
    
    
    class App extends React.Component {
      state = {
        message: 'this is message'
      }
      // 提供回调函数
      changeMessage = (newMsg) => {
        console.log('子组件传过来的数据:',newMsg)
        this.setState({
          message: newMsg
        })
      }
      render() {
        return (
          <div>
            <Son
              msg={this.state.message}
              // 传递给子组件
              changeMsg={this.changeMessage}
            />
          </div>
        )
      }
    }
    
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    4_生命周期

    请添加图片描述
    react教程

    4.1_挂载阶段

    钩子 函数触发时机作用
    constructor创建组件时,最先执行,初始化的时候只执行一次1. 初始化state 2. 创建 Ref 3. 使用 bind 解决 this 指向问题等
    render每次组件渲染都会触发只用于渲染UI(注意: 不能在里面调用setState()
    (与 挂载阶段 是同一个render)
    componentDidMount组件挂载(完成DOM渲染)后执行,初始化的时候执行一次1. 发送网络请求 2.DOM操作

    4.2_更新阶段

    钩子函数触发时机作用
    render每次组件渲染都会触发只用于渲染UI(与 挂载阶段 是同一个render)
    componentDidUpdate组件更新后(DOM渲染完毕)DOM操作,可以获取到更新后的DOM内容,不要直接调用setState

    5_Hook基础

    Hooks的出现解决了俩个问题 1. 组件的状态逻辑复用 2.class组件自身的问题

    1. 组件的逻辑复用
      在hooks出现之前,react先后尝试了 mixins混入,HOC高阶组件,render-props等模式
      但是都有各自的问题,比如mixin的数据来源不清晰,高阶组件的嵌套问题等等
    2. class组件自身的问题
      class组件就像一个厚重的‘战舰’ 一样,大而全,提供了很多东西,有不可忽视的学习成本,比如各种生命周期,this指向问题等等,而我们更多时候需要的是一个轻快灵活的’快艇’

    5.1_useState(用于参数的更新和渲染)

    使用步骤

    1. 导入 useState 函数
    2. 调用 useState 函数,并传入状态的初始值
    3. useState函数的返回值中,拿到状态和修改状态的方法
    4. 在JSX中展示状态
    5. 调用修改状态的方法更新状态
    import { useState } from 'react'
    
    function App() {
      // 参数:状态初始值比如,传入 0 表示该状态的初始值为 0
      // 返回值:数组,包含两个值:1 状态值(state) 2 修改该状态的函数(setState),名字可以自定义
      const [count, setCount] = useState(0)
      return (
        <button onClick={() => { setCount(count + 1) }}>{count}</button>
      )
    }
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    5.2_组件的更新过程

    • 函数组件第一次渲染
      1. 从头开始执行该函数组件中的代码逻辑
      2. 调用 useState(0) 将传入的参数作为状态初始值,即:0
      3. 渲染组件,此时,获取到的状态 count 值为: 0
    • 函数组件第二次渲染 (useState会被自动监听,所以当count改变时,就会重新渲染
      1. 点击按钮,调用 setCount(count + 1) 修改状态,因为状态发生改变,所以,该组件会重新渲染
      2. 组件重新渲染时,会再次执行该组件中的代码逻辑
      3. 再次调用 useState(0),此时 React 内部会拿到最新的状态值而非初始值,比如,该案例中最新的状态值为 1
      4. 再次渲染组件,此时,获取到的状态 count 值为:1

    5.3_useEffect

    1、什么是副作用

    副作用是相对于主作用来说的,一个函数除了主作用,其他的作用就是副作用。对于 React 组件来说,主作用就是根据数据(state/props)渲染 UI,除此之外都是副作用(比如,手动修改 DOM)

    常见的副作用

    1. 数据请求 ajax发送
    2. 手动修改dom
    3. localstorage操作

    useEffect函数的作用就是为react函数组件提供副作用处理的!

    2、监听变量变化

    useEffect注意事项(useEffect是在dom渲染之后才执行的)

    1. 不加依赖项:初始化+重新渲染

    2. 加[]:初始化执行一次

    3. 加特定的依赖项[count , name]就会监听这两种属性

    function App() {  
        const [count, setCount] = useState(0)  
        const [name, setName] = useState('str') 
        
        useEffect(() => {    
            console.log('副作用执行了')  
        }, [count],[name])  
        
        return (    
            <>      
             <button onClick={() => { setCount(count + 1) }}>{count}</button>      
             <button onClick={() => { setName('cp') }}>{name}</button>    
            </>  
        )
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3、在函数组件销毁的时候清除副作用

    import { useEffect, useState } from "react"
    
    function Test(){
            useEffect(() => {
            const timerId = setInterval(() => {
                console.log("1s打印一次")
            }, 1000)
            return () => {
                // 用来清理副作用的事情,当App组件被销毁的时候
                clearInterval(timerId)
            }
        })
        return (
            <div>
                {'test'}
            </div>
        )
    }
    
    const App = () => {
      const [flag, setFlag] = useState(true)
      return (
        <div>
              {flag?<Test/>:null}//点击按钮之后,flag变false,组件Test销毁
              <button onClick={() => setFlag(!flag)}>swicth</button>
        </div>
      )
    }
    
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    5.4_useRef

    使用场景

    在函数组件中获取真实的dom元素对象或者是类组件对象

    使用步骤

    1. 导入 useRef 函数
    2. 执行 useRef 函数并传入null,返回值为一个对象 内部有一个current属性存放拿到的dom对象(组件实例)
    3. 通过ref 绑定 要获取的元素或者组件
    import { useEffect, useRef } from 'react'
    
    function App() {  
        const h1Ref = useRef(null)  
        useEffect(() => {    
            console.log(h1Ref)  
        },[])  
        return (    
            <div>      
                <h1 ref={ h1Ref }>this is h1</h1>    
            </div>  
        )
    }
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5.5_useContext

    作用:将父组件的值可以直接传给孙子组件

    import { createContext, useContext } from 'react'
    // 创建Context对象
    const Context = createContext()
    
    function Foo() {  
        return <div>Foo <Bar/></div>
    }
    
    function Bar() {  
        // 底层组件通过useContext函数获取数据  
        const name = useContext(Context)  
        return <div>Bar {name}</div>
    }
    
    function App() {  
        return (    
            // 顶层组件通过Provider 提供数据    
            <Context.Provider value={'this is name'}>     
                <div><Foo/></div>    
            </Context.Provider>  
        )
    }
    
    export default App
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    6_react-router

  • 相关阅读:
    梯度下降算法中的数据标准化预处理(Python实现)
    壁挂式SIP网络有源音柱 SIP广播音柱 支持私有协议软件广播
    CSS文本属性和Emmet语法
    无线回程mesh组网从入门到精通【伸手党福利】打破行业壁垒!
    【开源】基于Vue和SpringBoot的创意工坊双创管理系统
    蓝桥杯刷题单
    LVS负载均衡-TUN模式(模拟不同网段)
    JsonPath详解
    生成模型的两大代表:VAE和GAN
    利用HFSS-API设计指数渐变传输线
  • 原文地址:https://blog.csdn.net/qq_43907296/article/details/127484503