4.27 react第一天

react 语法基础

  • 概念介绍

  • 项目初始化

  • 目录结构

  • 单文件组件 SFC 与 mustach语法 模板语法

  • 响应式数据 useState

  • react 合成事件

  • useEffect 生命周期与监听

  • 组件开发

    • 基础使用

    • 父传子

    • 子传父

    • 插槽

    • 上下文 context useContext 跨层级数据共享

  • react 状态管理库 redux redux-toolkit(最佳实践) mobx dva ...... reducer

  • react 路由 react-router-dom

  • UI库的使用 ant design 系列 antd mobile nutUi

1.react概念介绍

11年 facebook (meta) 开源react

第一次提出的概念:

  • 组件化开发

  • 响应式数据 数据驱动 最小粒度更新算法 性能远超vue ref reactive

  • 虚拟dom更新 驱动 真实dom更新 diff算法 fiber算法

  • react 语法 更加倾向原生JS

13年 10月 vue 发布了vue2.x ----22年

vue: 融合了 react 核心理念 和核心代码 融合和 anglur js 指令系统 14个指令

  • vue3语法 模仿了react 16.8语法

react 版本历史

  • <16.8 版本 基于 类的开发(面向对象的开发) 学习难度非常高

  • >16.8 版本 基于函数式的开发(面向函数开发) 学习难度较低 【大量的项目 都是基于函数式语法】

  • 目前最新react版本 19.x 16.x 17.x 18.x 19.x

2.项目初始化

react 组成部分:

  • react 核心语法 react

  • react 操作dom节点的库 react-dom

  • react 跨端原生开发(安卓 ios 小程序): react native RN

复制代码
  https://react.docschina.org/
  • 脚手架: 可以通过某种工具 快速的创建项目 (某种工具===脚手架工具)

    • vue vite vue-cli webpack

    • react vite create-react-app

2.1vite初始化 项目过程命令

复制代码
  
  pnpm create vite 项目名 --template react
复制代码
  
  pnpm install 
  pnpm run dev 

3.单文件组件 SFC

文件后缀 .js .jsx .tsx

一个函数 return 一段html 代码(被渲染到页面上 根据挂载的根节点确定渲染位置)

复制代码
  import './app.css'
  function App() {
    const xxx = 1000;
    let yyy = 2000;
    // mustach  {表达式}    <></>  有且只有一个根节点
    //  vue{{}} template     ES6 ${}
    return (
      <>
        <div id="app" >hello world---   {xxx}
          <p className="box"> 我是xxx 你好啊</p>
        </div>
        <div  >我是嘻嘻嘻</div>
      </>
    )
  }
  ​
  export default App;
复制代码
  
  import './app.css'
  export default () => {
    const a = 1100;
    return (
      <div className="box">
        {a}
      </div>
    )
  }

4.响应式数据 useState

数据改 页面改

页面改 数据改

复制代码
  
   const [变量,修改变量函数] = useState(初始值);
  //修改变量函数: 调用函数时,
  //1.首先修改变量的值
  //2.通过diff算法(递归)  比对 所有的dom节点(只是比对虚拟dom),找出使用了这个变量的dom节点
  //3.根据render函数,重新渲染涉及到的 真实 dom节点
复制代码
  
  import {useState} from 'react'
  ​
  export const ()=>{
      // 变量==响应式数据的特征
      //set变量 ==  接受一个 可以修改 这个变量的函数
      //之后修改数据变量,必须使用 set变量的方法进行修改  
      const [变量,set变量] = useState(初始值);
      const [a,setA] = useState(1000);
      
      const reduce = ()=>{
          //新数据如果是根据元数据改变过来的
          // 不要直接修改原数据的值  a-1  a--
          // 如果原值是引用数据类型,一定注意  深浅拷贝问题 
          //    修改引用数据类型时,应该先通过拷贝拿到原数据 给一个临时变量存起来 更改临时变量 最后setXXx修改响应式数据
          setA(a-1)
      }
  }
  ​
复制代码
  
  import './app.css'
  import { useState } from 'react';
  ​
  ​
  export default () => {
   const [a,setA] = useState(1000)
    const reduce = ()=>{
      // 异步修改函数  promise?  setTimeout 
      // 闭包: 永远拿到的都是老值
        setA(a-1) 
    }
    // const add = ()=>{
    //   setA(a+1)
    // }
    return (
      <>
        <button onClick={reduce}>-</button>
        <h1>{a}</h1>
        <button onClick={()=>setA(a+1)}>+</button>
      </>
  ​
    )
  }

5.react 合成事件

复制代码
  
  <div  on事件类型={事件的执行函数}>
复制代码
  
  const ()=>{
      const changeNum = ()=>{}
      return (<div  οnclick={changeNum}>)
  }
复制代码
  
  const ()=>{
      return (<div  οnclick={()=>{}}>)
  }
复制代码
  
  const ()=>{
          const changeNum = (num)=>{}
      return (<div  οnclick={()=>changeNum(1000)}>)
  }
  ​
复制代码
  
  const ()=>{
          const changeNum = (event,num)=>{}
      return (<div  οnclick={(event)=>changeNum(event,1000)}>)
  }

6.useEffect 副作用函数 hooks

useEffect 代替生命周期 (挂载完成,卸载之前)

​ <16.8版本 完整的生命周期(类组件为主 没有函数式组件)

useEffect 代替数据的监听(vue:watch computed)

复制代码
  
  import {useEffect} from 'react'
  export default  ()=>{
      //副作用:watch computed  就是监听的变量
      useEffect(()=>{},[副作用])
  }
  ​

生命周期 :

  • 初始化周期 init

  • 挂载周期 mounting

    • componentWillMount 组件挂载之前

    • componentDidMount 组件挂载之后 ----mounted

  • 更新周期 updation

  • 卸载周期 unMounting

    • componentWillUnmount 卸载之前 销毁之前

6.1 useEffect 代替生命周期

不去监听任何数据的改变 就代表的是 挂载完成周期

复制代码
  
  ​
  import {useEffect} from 'react'
  export default  ()=>{
     useEffect(()=>{
         //函数体:挂载完成执行的代码   componentDidMount
         return ()=>{
             //销毁周期的代码
         }
     },[])
    //这里一定要写[],不然就会死循环
  }
  ​

6.2 useEffect 监听某个数据的改变

注意:!!!

如果在监听某个变量的改变,useEffect 函数体中 千万不要 更改这个变量的值 的代码

副作用的[] 一定要写,不写会造成死循环

复制代码
  //变量1  变量2 任意1个变量的值发生改变 函数体就会自动执行一次
  import {useEffect} from 'react'
  export default  ()=>{
      
     useEffect(()=>{
         //函数体:挂载完成执行的代码   componentDidMount
         return ()=>{
             //销毁周期的代码
         }
     },[监听的变量1,监听的变量2...])
  }
  ​
复制代码
  
  //变量1  变量2 任意1个变量的值发生改变 函数题就会自动执行一次
  import {useEffect,useState} from 'react'
  export default  ()=>{
      const [a,setA] = useState(0)
     useEffect(()=>{
         //函数体:挂载完成执行的代码   componentDidMount
        setA(a+1)
     },[a])
       useEffect(()=>{
         //函数体:挂载完成执行的代码   componentDidMount
       
     },[监听的变量2])
  }
  ​

7.useRef 获取dom || 获取子组件的实例对象

复制代码
  
  import {useRef,useEffect} from 'react'
  ​
  ​
  export default ()=>{
      const boxRef = useRef(null); 
      
      useEffect(()=>{
          console.log(boxRef.current)   // <div ref={boxRef}> xxx </div>
      },[])
      
      return <div ref={boxRef}> xxx </div>
  }
复制代码
  
  import { useEffect,useState,useRef } from 'react'
  ​
  export default function App1() {
  ​
      const [num,setNum] = useState(100)
      const [a,setA] = useState(122)
  ​
       const boxRef = useRef(null);  
      // const timer = setInterval(() => {
      //     console.log('定时器');
      // },10000)
  ​
  ​
      useEffect(() => {
          // 挂载完成
          // let ulDom = document.querySelector('ul')
          // console.log(ulDom);
              console.log(boxRef.current);
               
          // 销毁周期 
          // return () => {
          //     clearInterval(timer)
          // }
      }, [])  
  ​
  ​
      const changeNum = () => {
          let num1 = num + 1
          setNum(num1)
          console.log(num1);
      }
      useEffect(()=>{
          console.log('变化了');
          console.log(num);
          console.log(a);
      },[num,a])
  ​
      return (
          <div>
              <div ref={boxRef} className="box">我是一个盒子</div>
              <ul>
                  <li>菜单{num}</li>
                  <li>菜单02</li>
                  <li>菜单03</li>
                  <li>菜单04</li>
                  <li>菜单05</li>
              </ul>
              <button onClick={changeNum}>递增</button>
              <button onClick={()=>setA(a+1)}>A</button>
          </div>
      )
  }
  ​

7.判断 三目运算

三目运算 使用场景: 显示隐藏 dom节点 动态样式 display:none 动态类名

复制代码
  
  import React from 'react'
  ​
  export default function App2() {
      const [gedner,setGender] = useState(0)
    return (
      <div>
            {gender%2==0?<span>男</span>:<span>女</span>} 
       </div>
    )
  }
  ​
复制代码
  
  import React,{useState} from 'react'
  ​
  ​
  // 子组件
  const getGender = (gender) => {
      return gender%2==0?<span>男</span>:<span>女</span>
  }
  ​
  // 导出一个默认的函数组件App2
  export default function App2() {
      // 使用useState钩子,初始化gender为0,并设置setGender函数用于更新gender的值
      const [gedner,setGender] = useState(0)
    return (
      <div>
            {getGender(gedner)}   
            <button onClick={()=>setGender(gedner+1)}>++++</button> 
       </div>
    )
  }
  ​
  • 判断成绩 >90 输出优秀,否则什么都不输出
复制代码
  
  import React,{useState} from 'react'
  ​
  export default function App3() {
      const [num,setNum] = useState(85)
    return (
      <div>
          {num>=90?<h1>优秀</h1>:null   }
      </div>
    )
  }

成绩范围

90 优秀

80 良好

70 中等

60 及格

60以下 不及格

复制代码
  
  import React,{useState} from 'react'
  ​
  ​
  const getGreade = (num)=>{
    let str = '不及格'
    switch(Math.floor(num/10)){
      case 10:
      case 9:str = '优秀'; break;
      case 8: str = '良好';break;
      case 7:str = '中等'; break;
      case 6: str = '及格';break;
      default:str = '不及格';
    }
  ​
    return  <h1>{str}</h1>
  }
  ​
  ​
  export default function App4() {
    const [num,setNum] = useState(46)
    
    return (
        <>
        {getGreade(num)}
          {/* {
            num>=90?<h1>优秀</h1>: num>=80?<h1>良好</h1>:num>=70?<h1>中等</h1>:num>=60?<h1>及格</h1>:<h1>不及格</h1>
          } */}
        
        
        </>
    )
  }
  ​
  • 动态样式操作
复制代码
  
  import React ,{useState} from 'react'
  ​
  export default function App5() {
      const [gender,setGender] = useState(0)
    return (
      <div>
          {/* 动态样式 */}
          <h1 style={{display:gender%2==0?'block':'none',background:'red'  } }>男</h1>
          <h1 style={{display:gender%2==1?'block':'none',background:'red'  } }>女</h1>
  ​
              <button onClick={()=>setGender(gender+1)}>+++</button>
      </div>
    )
  }
  ​
  • 动态类名

开关灯效果

复制代码
  
  import React, { useState } from 'react'
  import './App.css'
  ​
  export default function App6() {
      const [isLigiht, setIsLight] = useState(true)
      return (
          <>
              <div className={isLigiht?'box active':'box black'}>
  ​
              </div>
         
              <button onClick={() => setIsLight(true)}>开灯</button>
              <button onClick={() => setIsLight(false)}>关灯</button>
          </>
      )
  }
  ​
  • 选项卡 tab实现 17:05

希望清单的 标题 希望列表 添加希望

点击某个标题: 选中当前这个标题(添加选中样式) , 显示对应的内容区域

8.循环 map

循环数组 ||对象

最终目的: 必须要有 return 出来的 html代码到 页面上

复制代码
  
  import React,{useState } from 'react'
  ​
  export default function App8() {
      
  const [userList,setUserList] = useState([
      {name:'张麻子',age:40},
       {name:'黄四郎',age:35},
       {name:'马邦德',age:42},
  ])
  ​
  const add = ()=>{
   const obj = {name:'胡桂源',age:20}
  //  const list = [...userList]
  //  list.push(obj)
  // // setUserList(userList)  //地址没有发生改变 ,所以不会重新渲染
  // // 需要临时的空的数组 有新的地址  装所有的新数据,再调用修改变量的值 set方法 才可以有响应式数据的特征
  //  setUserList(list)
  ​
  userList.push(obj)
  setUserList([...userList])  //地址没有发生改变 ,所以不会重新渲染
  // 需要临时的空的数组 有新的地址  装所有的新数据,再调用修改变量的值 set方法 才可以有响应式数据的特征
  ​
  }
  ​
    return (
      <>
      <button onClick={add}>添加数据</button>
          {
              userList.map((item,index)=>{
                  return <p key={index}>姓名:{item.name};年龄:{item.age}</p>
              })
          }
  ​
      </>
    )
  }
复制代码
  
  const [students,setStudents] = useState([
      {sno:'12000',name:'纪英龙',greade:95},
         {sno:'1202200',name:'查其才',greade:85},
      {sno:'123330',name:'蒋盛林',greade:55},
  ])
  //渲染默认数据
  //点击事件  添加一个对象     {sno:'222',name:'xxxx',greade:55},
  // 删除按钮 删除对应的数据  
  ​

9.受控组件 与 非受控组件|表单 获取数据

非受控组件 : 通过 useRef 获取到dom ,再通过dom节点获取表单数据 antd

受控组件: 通过useState 做数据的绑定 加上 onChange 事件 e.target.value 然后赋值给那个变量useState=e.target.value

复制代码
  
  import React,{useRef} from 'react'
  ​
  export default function App9() {
      // 非受控组件  useRef
      const accountRef = useRef(null);
      const passwordRef = useRef(null);
  ​
      const saveBtn = () => {
          console.log(accountRef.current.value);
          console.log(passwordRef.current.value);
      }
      
    return (
      <>
          账号: <input type="text" ref={accountRef} />
          密码: <input type="password" ref={passwordRef}/>
          <button onClick={saveBtn}>提交</button>
      </>
    )
  }
  ​
复制代码
  
  import React,{useState} from 'react'
  ​
  export default function App9() {
      const [formData,setFormData] = useState({account:'',password:''})
  ​
      const saveBtn = () => {
         console.log(formData);
         
      }
      const change = (data)=>{
          setFormData(data)
      }
  ​
    return (
      <>
          账号: <input type="text"  onChange={(e)=>change({account:e.target.value, password:formData.password})}/>
          密码: <input type="password" onChange={(e)=>change({account:formData.account, password:e.target.value})} />
          <button onClick={saveBtn}>提交</button>
      </>
    )
  }
相关推荐
橙子199110164 分钟前
谈谈 Kotlin 中的构造方法,有哪些注意事项?
java·前端·kotlin
*neverGiveUp*19 分钟前
本地分支git push 报错 fatal: The current branch XXXX has no upstream branch.
前端·git·gitea
AaronZZH22 分钟前
为什么现代CSS应该选择OKLCH:从颜色科学到设计系统革新
前端·css
CaseyWei1 小时前
JS实现直接下载PDF文件
前端·javascript
球球和皮皮1 小时前
Babylon.js学习之路《七、用户交互:鼠标点击、拖拽与射线检测》
javascript·3d·前端框架·babylon.js
pianmian11 小时前
3dczml时间动态图型场景
前端·javascript·数据库
编程大全2 小时前
45道工程模块化高频题整理(附答案背诵版)
前端·工程化
君的名字2 小时前
怎么判断一个Android APP使用了React Native 这个跨端框架
android·react native·react.js
好奇的菜鸟2 小时前
如何升级 npm:从版本管理到最佳实践
前端·npm·node.js
iamtsfw2 小时前
从头实现react native expo本地生成APK
javascript·react native·react.js