react

前端基础知识

块级作用域之var与let与const

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    {
        let a=10;
        var as=10;
    }
   // console.log(a);
    console.log(as);

    for(let aindex=0; aindex<10 ;aindex++){
        console.log("let循环"+aindex);
    }
  //  console.log(aindex);

    for(var asindex=0; asindex<10 ;asindex++){
        console.log("var循环"+asindex);
    }
    console.log(asindex);
</script>
</html>

var 无区级快,let有区级快,const有区级快只能赋值一次。

赋值

//解析赋值
    // const name=["孙悟空","猪八戒"];
    // let [a,b]=name;
    // console.log(a);
    // let [,bs]=name;
    // console.log(bs);
    // const nameList=["小红","小明","小刚","小王"];
    // let [a,b,...c]=nameList;//剩余数组必须是最后一个 [a,...b,c]会出现错误
    // console.log(a);
    // console.log(b);
    // console.log(c);
    obj={
        Name:"岳阳大学",
        Age:"40",
        Address:"湖南岳阳"
    }
    let a,b,c;
    // ({Name:a,Age:b,Address:c}=obj)//不能去掉()
    // console.log(a,b,c);
    //第二种
    // const {Name,Age,Address}=obj;
    // console.log(Name,Age,Address);

    //交换值
     a=10;
     b=20;
     [a,b]=[b,a];
     console.log(a+"he"+b);

展开

 function addition (a,b,c){
        return a+b+c;
    }
    const umber=[1,1,3];
    let sum=addition(...umber);
    console.log(sum);

    const copyNum=[2,3,...umber];
    console.log(copyNum);
    
   const obj={
        Name:"岳阳大学",
        Age:"40",
        Address:"湖南岳阳"
    }

    let objCopy={Name:"民族大学",...obj}
    let objCopys={...obj,Name:"民族大学"}
    console.log("展开前"+objCopy.Name);
    console.log("展开后"+objCopys.Name);//如果名称一样后面的值将会覆盖之前的值

箭头函数

  /*
    箭头函数没有arguments
    箭头函数中没有自己的this
        他的this总是外层作用域的this
    箭头函数中的this无法通过call()、apply()、bind()修改
    箭头函数无法作为构造函数
    */
    let sum=a=>console.log(a);
    console.log(sum(12));

    //arguments arguments 是一个对应于传递给函数的参数的类数组对象
    function Hanshu(){
        console.log(arguments.length);
    }
    let hanshu=(...arg)=>{
        //console.log(arguments.length);//系统将会出现错误
        //index箭头函数.html:29 Uncaught ReferenceError: arguments is not defined
    };
    //this指向
    function pointToThis(){
        console.log("函数");
        console.log(this);
    }
    let Pointhis=()=>{
        console.log("箭头函数");
        console.log(this);
    };
   let obj={
    Point:function(){
        let Pointhis=()=>{
            console.log("嵌入函数中的箭头函数");
            console.log(this);
        };
        console.log("嵌入函数本身");
            console.log(this);
        Pointhis();
    }
   }
    pointToThis();Pointhis();obj.Point();

模快化

export default 默认
import a from "./路径" 路径一定要带./

类的基本使用

/*
  类
  constructor构造函数
  */
 class Person{
    Name='';
    Age=0;
    constructor(name,age){
        this.Name=name;//此时this指向person
        this.Age=age;
    }
    run(){
        console.log("我是person方法");
    }
 }
 const personObj=new Person("小明",18);
 console.log(personObj.Name);
 personObj.run();

类的this

 //"use strict";
    /*
    this指向
    "use strict";严格模式
    class默认为严格模式
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    this指向不稳定

    */
   class Person{
     Name="";
     Age=0;
    // fu(){ console.log(this);}

     fu=()=>{console.log(this);}
   }

   const per=new Person();
   per.fu();
   const fus=per.fu;
   fus();

类的继承

 /*
    类的继承
    继承的关键词 extends
    重写方法
        1、重写方法直接重新输入名称
        2、但是在参数的时候需要注意
            1、用constructor构造函数必须将super()放在首句
    */
    class Animal {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
        sayHello = () => {
            console.log("动物叫声");
        }
    }


    class Dog extends Animal {
        constructor(name,age,length){
            super(name,age);
            this.legth=length
        }
        sayHello = () => {
            console.log("汪汪汪");
        }
    }

    class Snake extends Animal {
        sayHello = () => {
            console.log("嘶嘶嘶");
        }
    }
    new Dog().sayHello();
    new Snake().sayHello();
    const dogobj=new Dog("晓玲",12,24);
    console.log(dogobj.name,dogobj.age,dogobj.legth);

类的静态属性

class Person{
        static name="ok";

        static fu=()=>{
            console.log(this);
        }
    }

    console.log(Person.name);
    Person.fu();

React使用

初始react

在以下都是18.版本的使用

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React demo</title>

    <script src="https://cdn.staticfile.org/react/18.0.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/18.0.0/umd/react-dom.development.js"></script>
    

</head>

<body>
    <div id="app">
        
    </div>
</body>
<!-- <script>
    const biaoqian=document.createElement("div");
    biaoqian.innerText="Hello Word!"
    const ids=document.getElementById("app");
    ids.after(biaoqian);
</script> -->

<script>
    //这是18.0用的方法
    const button=React.createElement('button',{},'我是按钮');
    const root=ReactDOM.createRoot(document.getElementById('app'));
    root.render(button);
    // ReactDOM.render(
    //    <div>Hello Word!</div>,
    //     document.getElementById('app'));
</script>
</html>

jsx文件

使用的是声明式开发。

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React demo</title>

    <script src="https://cdn.staticfile.org/react/18.0.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/18.0.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

</head>

<body>
    <div id="app">

    </div>
</body>
<!-- <script>
    const biaoqian=document.createElement("div");
    biaoqian.innerText="Hello Word!"
    const ids=document.getElementById("app");
    ids.after(biaoqian);
</script> -->

<script type="text/babel">//这就是jsx的含义如果不加这个text/babel 与相应的js应用将会是失败就无法使用声明式编程标签
    //创建一个<button>我是按钮</button>
    //命令编程
    // const button=React.createElement('button',{},'我是按钮');
    //声明式编程
    const button=<button>react開始</button>;
    const root=ReactDOM.createRoot(document.getElementById('app'));
    root.render(button);
</script>

</html>

jsx文件补充

  1. jsx不是字符串不要加引号
  2. jsx中的html标签要小写,大写是组件
  3. jsx有且只有一个根标签
  4. jsx中的标签必须也得正确
  5. 在jsx中使用{}嵌入表达式
    1. -必须写有值的语句就是表达式
  6. 如果表达式是空值、布尔值、undefined这些值将不会显示
  7. 在jsx中,属性可以直接在标签中使用 ***class要写为className、style中必须用对象设置不能用style=“background-color:red”,在这个对象中带-的属性必须用驼峰式命名
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React demo</title>

    <script src="https://cdn.staticfile.org/react/18.0.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/18.0.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

</head>

<body>
    <div id="app">

    </div>
</body>

<script type="text/babel">
    /*
    jsx注意事项
        1.jsx不是字符串不要加引号
        2.jsx中的html标签要小写,大写是组件
        3.jsx有且只有一个根标签
        4.jsx中的标签必须也得正确
        5.在jsx中使用{}嵌入表达式
            -必须写有值的语句就是表达式
        6.如果表达式是空值、布尔值、undefined这些值将不会显示
        7.在jsx中,属性可以直接在标签中使用 ***class要写为className、style中必须用对象设置不能用style="background-color:red",在这个对象中带-的属性必须用驼峰式命名****
    */
    const name = "小明";
    const div = <div>
        我的名字叫做{name}
        <button id="btn" onClick={()=>{alert("5")}} className="box1" style={{backgroundColor:"red"}}>点击原地</button>
    </div>;
    const root = ReactDOM.createRoot(document.getElementById('app'));
    root.render(div);
</script>

</html>

渲染列表数据

简单数据渲染

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>React demo</title>

    <script src="https://cdn.staticfile.org/react/18.0.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/18.0.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

</head>

<body>
    <div id="app">

    </div>
</body>

<script type="text/babel">
    /*
    简单数据渲染
    
    */
    const data = ['Item 1', 'Item 2', 'Item 3'];
    const datas=data.map(((item,index)=>{
       return <li key={index}>{item}</li>
       }));
    const ul = <ul>
       {datas}
    </ul>;
    const root = ReactDOM.createRoot(document.getElementById('app'));
    root.render(ul);
</script>

</html>

脚手架react.js

命令行

  1. npx react-create-app react-basic react-basic 为项目名称
  2. mkdir 创建文件夹
  3. rmdir 删除文件夹
  4. echo ‘写入内容’>文件名
  5. cd… 返回上一级
  6. npm uninstall 包名

Jsx中js使用

CRA项目SRC目录

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方法与变量识别
  1. 使用引导转递字符串
  2. 使用JavaScript变量
  3. 函数调用和方法调用
  4. 使用JavaScript

App.js

const message="这还是一句话";
const getHappiness=()=>{
  return "幸福这东西,如果不放弃些什么,就无法得到它";
}
function App() {
  return (
    <div className="App">
      这是一句话<br/>
     {/*1.使用引号传递字符串 */}
     {'这也是一句话'}<br/>
     {/* 2.使用JavaScript变量 */}
     {message}<br/>
     {/* 函数调用和方法调用 */}
     {getHappiness()}<br/>
     {new Date().getDate()}
     {/* 使用js对象 */}
     <div style={{color:"red"}}>这是红色的</div>
    </div>
  );
}

export default App;

数据渲染
  1. {/* 列表渲染 */}
  2. {/* map 循环那个结构 return结构 */}
  3. {/* 注意事项:加上一个独一无二的key 字符串或者number id */}
  4. {/* key的作用:React框架内部使用 提升更新性能的 */}
const list = [
  { id: 1001, name: "Vue" },
  { id: 1002, name: "React" },
  { id: 1003, name: "Angular" },
];
function App() {
  return <div className="App">
    {/* 列表渲染 */}
    {/* map 循环那个结构 return结构 */}
    {/* 注意事项:加上一个独一无二的key 字符串或者number id */}
    {/* key的作用:React框架内部使用 提升更新性能的 */}
    <ul>
      {list.map(item=><li key={item.id}>{item.name}</li>)}
    </ul>
  </div>;
}

export default App;

数据条件判断
  1. 第一种&& {yesno&&我从没觉得孤独,说的浪漫些,我完全自由}
  2. 第二种? {yesno?夕阳总会落在你身上,你也会快乐一场。:直到遇见你那一刻 我的星河才亮了起来.}
  3. 第三种自己定义 ()=>{}
const yesno=true;
const thems=1;
let themList=(them)=>{
  if(them===0){
    return <span>蜀道之难,难于上青天!</span>
  }
  else if(them===1){
    return <span>蚕丛及鱼凫,开国何茫然!</span>
  }
  else if(them===2){
    return <span>上有六龙回日之高标,下有冲波逆折之回川。</span>
  }
};
function App() {
  return <div className="App">
    {yesno&&<span>我从没觉得孤独,说的浪漫些,我完全自由</span>}<br/>
    {yesno?<span>夕阳总会落在你身上,你也会快乐一场。</span>:<span>直到遇见你那一刻 我的星河才亮了起来.</span>}<br/>
    {themList(thems)}
  </div>;
}

export default App;

前端事件
  1. 事件一般是驼峰式
  2. 事件获取可以通过{(e)=>{方法名(e)}}的方式
const GetName=()=>{
  console.log("东海龙王");
}
const GetEOrName=(e,Name)=>{
  console.log(e,"我的名字是",Name);
}
function App() {
  return <div className="App">
    <button onClick={(e)=>{GetEOrName(e,"北海龙王")}}>点我</button>
  </div>;
}

export default App;

React组件

一个组件时页面的一部分,组件之间可以重复嵌套,也可以重复多次使用

必须大写

const GetName=()=>{
  console.log("东海龙王");
}
const Buttons=()=>{
  return <button onClick={GetName}>点我</button>
}
function App() {
  return <div className="App">
    {/* 闭合式 */}
    <Buttons/>
    {/* 双标签 */}
    <Buttons></Buttons>
  </div>;
}

export default App;

useState组件使用

useState是一个可以改变数据还可以使ui视图发生改变

对于复杂的类型处理 useState({name:“ss”}); setCout({…count,naem:“dd”});

只能在顶层或者自定义Hook中使用使用不能在if和for中

import {useState} from "react"
function App() {
  
let [count,setCount]=useState(0); 
ojoi
const setCounts=()=>{
    count++;
    consle.log(count);
  setCount(count+1);
} 
  return <div className="App">
    <button onClick={setCounts}>{count}</button>
  </div>;
}

export default App;

样式控制
  1. 第一种直接在dom元素使用{{color:“aqua”}}
  2. 第二种在外面使用对象数据来进行元素编辑,const styles={color:red}
  3. 第三种在外部创建css文件,后使用import “./css文件名.css”,在需要样式的文件上附上值
import { useState } from "react"
import "./index.css"
const styles={
  color:"red"
}

const App=()=>{
  const [count,setCount]=useState({name:"58"});
  const SetCounts=()=>{
    setCount({...count,name:"88"});
  }
  const Buttons=()=>{
    return<div>
      <button className="pri" onClick={SetCounts}>{count.name}</button>
    <p style={styles}>sss</p>
    <p style={{color:"aqua"}}>ddddd</p>
    </div>
  }
  return <div id="App">
    <Buttons />
  </div>
}

export default App
lodash使用

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。

官网地址

  1. 输入 npm i --save lodash
  2. 利用useState组件里面的set来刷新变量和ui
import { useState } from "react";
import _ from "lodash";

function App() {
  //用户信息
  const User = {
    Userid: "0304",
    Name: "花开花落",
  };
  //书籍
  let Namelist = [
    { id: 1, Name: "林立", Userid: "03014" },
    { id: 52, Name: "监视", Userid: "03014" },
    { id: 3, Name: "云霄", Userid: "03404" },
    { id: 64, Name: "不糊", Userid: "03044" },
    { id: 5, Name: "逍遥", Userid: "0304" },
  ];
  //排序方式
  let orderObjList = [
    {
      Labe: "升序",
      Value: "asc",
    },
    {
      Labe: "|",
      Value: "",
    },
    {
      Labe: "降序",
      Value: "desc",
    },
  ];
  let [orders, Setoreder] = useState(orderObjList);
  let [type, Settype] = useState("");
  let [Names, SetNames] = useState("");
  let [Namelists, SetNamelist] = useState(Namelist);
  const SetNameListFunction = () => {
    //添加数据
    let idNum = Namelists.length + 1;
    Namelists.push({ id: idNum, Name: Names, Userid: "0304" });
    SetNamelist(Namelists);
    console.log(Namelists);
    SetNames("");
  };
  //删除
  const DeleteNameList = (id) => {
    const updatedNamelist = Namelists.filter((item) => item.id !== id);
    SetNamelist(updatedNamelist); // 更新名字列表
  };
  //lodsah 排序
  const orderyfunction = (types) => {
    Settype(types);
    SetNamelist(_.orderBy(Namelists, ["id"], types !== "" ? types : "asc"));
  };
  return (
    <div className="App">
      <div>
        <input
          type="text"
          value={Names}
          onChange={(e) => SetNames(e.target.value)}
        ></input>
        <button onClick={SetNameListFunction}>添加书籍</button>
      </div>
      <br />
      <div>
        {orders.map((item) => (
          <span
            key={item.Value}
            onClick={() => orderyfunction(item.Value)}
            style={type === item.Value ? { color: "red" } : {}}
          >
            {item.Labe}
          </span>
        ))}
      </div>
      <h1>喜欢书籍类型</h1>
      <ul>
        {Namelists.map((item) => (
          <li key={item.id}>
            {item.Name}
            {item.Userid === User.Userid && (
              <button
                onClick={() => DeleteNameList(item.id)}
                style={{ color: "red" }}
              >
                删除
              </button>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

input数据赋值
  1. 通过e的方式来获得数据,e.target 表示触发事件的 DOM 元素
import { useState } from "react";

const App=()=>{
  let[Names,SetNames]=useState("s");
  return (
    <div id="App">
      123
   <input type="text" value={Names} onChange={(e)=>{SetNames(e.target.value)}}/>
  </div>
  )
}

export default App
获取dom元素进行聚焦
  1. 首先将useRef导入
  2. 实列化useRef
  3. 再将ref=实例化useRef组件的值的参数名称放入dom元素中
  4. useRef参数名.current为Dom元素,.current后面接入.value为Dom元素的值
  5. onsole.log() 主要用于输出文本信息,而 console.dir() 则更适合用于显示对象的详细结构。
import { useRef } from "react";
//onsole.log() 主要用于输出文本信息,而 console.dir() 则更适合用于显示对象的详细结构。
const App=()=>{
  const inputRef=useRef(null);
  const clickHarvest=()=>{
    console.dir(inputRef.current);
    console.log(inputRef.current.value);
  }
  return (
    <div id="App">
    <input type="text" ref={inputRef} />
    <button onClick={clickHarvest}>点击获取Dom元素</button>
  </div>
  )
}

export default App
import { useRef, useState } from "react";

//onsole.log() 主要用于输出文本信息,而 console.dir() 则更适合用于显示对象的详细结构。
const App=()=>{
  let [values,setValues]=useState("");
  const inputRef=useRef(null);
  const clickHarvest=()=>{
    console.dir(inputRef.current);
    console.log(inputRef.current.value);
    //进行值清空
    setValues("");
    //进行聚焦
    inputRef.current.focus();   
  }
  return (
    <div id="App">
    <input type="text" ref={inputRef} value={values} onChange={(e)=>{setValues(e.target.value)}} />
    <button onClick={clickHarvest}>点击获取Dom元素</button>
  </div>
  )
}

export default App
插件day.js与uuid.js

安装 | Day.js中文网 (fenxianglu.cn)

uuid - npm (npmjs.com)

import { useState } from "react";
import _ from "lodash";
import { v4 as uuidv4 } from 'uuid';
import dayjs from 'dayjs';

function App() {
  //用户信息
  const User = {
    Userid: "0304",
    Name: "花开花落",
  };
  //书籍
  let Namelist = [
    { id: 1, Name: "林立", Userid: "03014",dateTime:"03-11 14:24"},
    { id: 52, Name: "监视", Userid: "03014",dateTime:"03-11 14:24" },
    { id: 3, Name: "云霄", Userid: "03404" ,dateTime:"03-11 14:24"},
    { id: 64, Name: "不糊", Userid: "03044" ,dateTime:"03-11 14:24"},
    { id: 5, Name: "逍遥", Userid: "0304" ,dateTime:"03-11 14:24"},
  ];
  //排序方式
  let orderObjList = [
    {
      Labe: "升序",
      Value: "asc",
    },
    {
      Labe: "|",
      Value: "",
    },
    {
      Labe: "降序",
      Value: "desc",
    },
  ];
  let [orders, Setoreder] = useState(orderObjList);
  let [type, Settype] = useState("");
  let [Names, SetNames] = useState("");
  let [Namelists, SetNamelist] = useState(_.orderBy(Namelist,['id'],"asc"));
  const SetNameListFunction = () => {
    //添加数据
    let idNum = uuidv4();
    let datetime=dayjs().format("MM-DD HH:mm");
    Namelists.push({ id: idNum, Name: Names, Userid: "0304",dateTime:datetime  });
    SetNamelist(Namelists);
    console.log(Namelists);
    SetNames("");
  };
  //
  //删除
  const DeleteNameList = (id) => {
    const updatedNamelist = Namelists.filter((item) => item.id !== id);
    SetNamelist(updatedNamelist); // 更新名字列表
  };
  //lodsah 排序
  const orderyfunction = (types) => {
    Settype(types);
    SetNamelist(_.orderBy(Namelists, ["id"], types !== "" ? types : "asc"));
  };
  return (
    <div className="App">
      <div>
        <input
          type="text"
          value={Names}
          onChange={(e) => SetNames(e.target.value)}
        ></input>
        <button onClick={SetNameListFunction}>添加书籍</button>
      </div>
      <br />
      <div>
        {orders.map((item) => (
          <span
            key={item.Value}
            onClick={() => orderyfunction(item.Value)}
            style={type === item.Value ? { color: "red" } : {}}
          >
            {item.Labe}
          </span>
        ))}
      </div>
      <h1>喜欢书籍类型</h1>
      <ul>
        {Namelists.map((item) => (
          <li key={item.id}>
            {item.Name}
            {item.dateTime}
            {item.Userid === User.Userid && (
              <button
                onClick={() => DeleteNameList(item.id)}
                style={{ color: "red" }}
              >
                删除
              </button>
            )}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default App;

组件之间的通信
父传子
  1. 使用name={}传递给子组件
  2. 子组件用props接受
  3. props可以接受任意类型数据
  4. 在父组件中用子组件然后包裹一个标签会自动变为子组件的子组件
//父传子
//1、使用name={}传递给子组件
//2、子组件用props接受
//3、props可以接受任意类型数据
//4、在父组件中用子组件然后包裹一个标签会自动变为子组件的子组件


const Part=(props)=>{
  return (
    <div>
      <p>this{props.names}
      {props.children}</p>
    </div>
  );
}


const App=()=>{
 const Names="这是父组件里面的";
  return (
    <div id="App">
    <Part names={Names}><span>孙子</span></Part>
  </div>
  )
}

export default App
子传父
  1. 核心:在子组件中调用父组件中的函数并传递实参
//子传父
//核心:在子组件中调用父组件中的函数并传递实参

import { useState } from "react";

const APPSon=({onPropsFunction})=>{
  const Name="儿子";
  return(
    <div>
      <button onClick={()=>{onPropsFunction(Name)}}>点击传递</button>
    </div>
  );
}



const App=()=>{
 let [Name,setName]= useState("")
 const getName=(Names)=>{
  console.log(Names);
  setName(Names);
 };
  return (
    <div id="App">
      {Name}
    <APPSon onPropsFunction={getName}></APPSon>
  </div>
  )
}

export default App
兄弟之间传递参数
  1. 先将A中参数传递给父组件
  2. 再将父组件参数传递给B就完成了A到B中数据传递
//兄弟之间传递参数
//先将A中参数传递给父组件
//再将父组件参数传递给B就完成了A到B中数据传递

import { useState } from "react";




const A=({onPropsFunction})=>{
  const Name="我是A,B是我的好朋友我要送她个礼物。"
  return(
    <div>
      this is A comments;
      <button onClick={()=>{onPropsFunction(Name)}}>点击</button>
    </div>
  );
}

const B=(props)=>{
  return(
    <div>
      this is B comments;{props.name}
    </div>
  );
}

const App=()=>{
 let [Name,setName]= useState("")
 const getName=(Names)=>{
  console.log(Names);
  setName(Names);
 };
  return (
    <div id="App">
      this is App comment;
     <A onPropsFunction={getName}></A>
     <B name={Name}></B>
  </div>
  )
}

export default App
跨层传递参数
  1. 列如A到C中间有个B这种就叫做跨层
  2. 使用createContext方法创建一个上下文对象Ctx
  3. 在顶层组件(App)中通过Ctx.Provider组件提供数据
  4. 在底层组件(B)中通过useContext钩子函数获取消费数据
  5. 他不局限于底层和高层之间也可以是父子之间
//兄弟之间传递参数
//先将A中参数传递给父组件
//再将父组件参数传递给B就完成了A到B中数据传递

import { createContext, useContext } from "react";



const usercontextobj=createContext();



const A=()=>{
  
  return(
    <div>
      this is A comments;
      <B></B>
    </div>
  );
}

const B=()=>{
  const Name=useContext(usercontextobj);
  return(
    <div>
      this is B comments;{Name}
    </div>
  );
}

const App=()=>{
  //注册useContext函数
  

  const Name="我是从App里来";
  return (
    <div id="App">
      <usercontextobj.Provider value={Name}>
      this is App comment;
      <A ></A>
      </usercontextobj.Provider>
  </div>
  )
}

export default App
useEffect组件
  1. http://geek.itheima.net/v1_0/channels
  2. 列句
  3. useEffect(()=>{ },[]);第一个参数为当前要执行事件,第二个事件为执行时机
  4. 当[]为空的时候时机为组件初始渲染和组件更新时执行
  5. 当为[]的时候时机为旨在初始渲染的时候执行一次
  6. 当[]添加特殊依赖项时机为组件初始渲染和特定的依赖变化时执行
  7. 副作用执行时机是在组件卸载时自动执行return()=>{}

简单的useEffect使用

import { useEffect, useState } from "react"
const URL="http://geek.itheima.net/v1_0/channels"
const App=()=>{
  let [list,setList]=useState([]);
  useEffect(()=>{
    //额外参数,获取频道
    async function getList(){
      const res=await fetch(URL);
      const json =await res.json();
      console.log(json);
      setList(json.data.channels);
    };
    getList();
  },[]);
  
  return (
    <div id="App">
   this is App;
   <ul>
    {list.map((item)=>{
      return <li key={item.id}>{item.name}</li>
    })}
   </ul>
  </div>
  )
}

export default App

当为空的时候

import { useEffect, useState } from "react"


const App=()=>{
  const [Name,setName]=useState(0);
  useEffect(()=>{
    console.log("已经执行");
  });
  return (
    <div id="App">
      <button onClick={()=>{setName(Name+1)}}>{Name}</button>
  </div>
  )
}

export default App

当为[]的时候

import { useEffect, useState } from "react"


const App=()=>{
  const [Name,setName]=useState(0);
  useEffect(()=>{
    console.log("已经执行");
  },[]);
  return (
    <div id="App">
      <button onClick={()=>{setName(Name+1)}}>{Name}</button>
  </div>
  )
}

export default App

当[]添加特殊数据

import { useEffect, useState } from "react"


const App=()=>{
  const [Name,setName]=useState(0);
  useEffect(()=>{
    console.log("已经执行");
  },[Name]);
  return (
    <div id="App">
      <button onClick={()=>{setName(Name+1)}}>{Name}</button>
  </div>
  )
}

export default App

副作用

import  { useEffect,useState } from "react"
const Aop=()=>{
  useEffect(()=>{
    const timer=setInterval(()=>{
      console.log("计时器");
    },1000);
    return()=>{
      clearInterval(timer);
    };
  },[]);
  return(
    <div>
      <span>this is Aop</span>
    </div>
  );
}
const App=()=>{
  const [app,setApp]=useState(true)
  return (
    <div id="App">
      this is App
      {app&&<Aop/>}
      <button onClick={()=>{setApp(false)}}>点击卸载程序</button>
    </div>
  )
}

export default App
自定义hook

分装自定义hook思路

  1. 申明一个use打头的函数
  2. 在函数体内封装可复用的逻辑
  3. 把组件中用到的状态或者回调retrun出去
  4. 在那个组件中用到这个逻辑,就执行这个函数,解析出来状态和回调进行使用
import {useState} from "react"

const useShowOrHide=()=>{
  const [state,setState]=useState(true);
  const setStatefunction=()=>{
    const statecopy=!state;
    setState(statecopy);
  }
  return{
    state,
    setStatefunction
  };
};

//比如用按钮控制一个div显示隐藏
const App=()=>{
  const {state,setStatefunction}=useShowOrHide();
  return (
    <div id="App">
     {state&&<div>this is App</div>}
     <button onClick={()=>{setStatefunction()}}>点击</button>
    </div>
  )
}

export default App
json-server模拟服务

json-server - npm (npmjs.com)

  1. 先在react的项目中加入一个json文件放入数据
  2. 然后安装npm install json-server -D
  3. 最后可以配置命令行json-server ./serve/data.json --port 8888或者直接执行,db为你当前json文件名字
  4. 执行后看到一个表情就执行成功了
  5. 然后新建一个终端,安装axios npm install axios
  6. 然后调用与使用axios.get(“url”)
import { useState,useEffect } from "react";
import { useRef } from "react";
import _ from "lodash";
import { v4 as uuidv4 } from 'uuid';
import dayjs from 'dayjs';
import axios from 'axios';

//封装初始数据hook
function useGetList(){
  let [Namelists, SetNamelist] = useState([]);
  useEffect(()=>{
    async function getDate(){
      const res=await axios.get("http://localhost:3004/list");
      SetNamelist(res.data);
    };
    getDate();
  },[])
  return{
    Namelists, SetNamelist
  };
}

//封装 item
const BookItems=({item,Ondel,User})=>{
  return<li key={item.id}>
  名称:
  {item.Name},
  时间:
  {item.dateTime}
  {item.Userid === User.Userid && (
    <button
      onClick={() => Ondel(item.id)}
      style={{ color: "red" }}
    >
      删除
    </button>
  )}
</li>;
}
function App() {
  //用户信息
  const User = {
    Userid: "0304",
    Name: "花开花落",
  };
  //书籍
  // let Namelist = [
  //   { id: 1, Name: "林立", Userid: "03014",dateTime:"03-11 14:24"},
  //   { id: 52, Name: "监视", Userid: "03014",dateTime:"03-11 14:24" },
  //   { id: 3, Name: "云霄", Userid: "03404" ,dateTime:"03-11 14:24"},
  //   { id: 64, Name: "不糊", Userid: "03044" ,dateTime:"03-11 14:24"},
  //   { id: 5, Name: "逍遥", Userid: "0304" ,dateTime:"03-11 14:24"},
  // ];
  //获取dom元素进行聚焦
  const userefObj=useRef(null);
  //排序方式
  let orderObjList = [
    {
      Labe: "升序",
      Value: "asc",
    },
    {
      Labe: "|",
      Value: "",
    },
    {
      Labe: "降序",
      Value: "desc",
    },
  ];
  let [orders, Setoreder] = useState(orderObjList);
  let [type, Settype] = useState("");
  let [Names, SetNames] = useState("");
  //let [Namelists, SetNamelist] = useState(_.orderBy(Namelist,['id'],"asc"));
 //数据展示
 let {Namelists, SetNamelist}=useGetList();
  const SetNameListFunction = () => {
    //添加数据
    let idNum = uuidv4();
    let datetime=dayjs().format("MM-DD HH:mm");
    Namelists.push({ id: idNum, Name: Names, Userid: "0304",dateTime:datetime  });
    SetNamelist(Namelists);
    console.log(Namelists);
    //重新将input框值变为空
    SetNames("");
    //重新聚焦focus();
    userefObj.current.focus();
  };
  //
  //删除
  const DeleteNameList = (id) => {
    const updatedNamelist = Namelists.filter((item) => item.id !== id);
    SetNamelist(updatedNamelist); // 更新名字列表
  };
  //lodsah 排序
  const orderyfunction = (types) => {
    Settype(types);
    SetNamelist(_.orderBy(Namelists, ["id"], types !== "" ? types : "asc"));
  };
  return (
    <div className="App">
      <div>
        <input
          type="text"
          value={Names}
          ref={userefObj}
          onChange={(e) => SetNames(e.target.value)}
        ></input>
        <button onClick={SetNameListFunction}>添加书籍</button>
      </div>
      <br />
      <div>
        {orders.map((item) => (
          <span
            key={item.Value}
            onClick={() => orderyfunction(item.Value)}
            style={type === item.Value ? { color: "red" } : {}}
          >
            {item.Labe}
          </span>
        ))}
      </div>
      <h1>喜欢书籍类型</h1>
      <ul>
        {Namelists.map((item) => 
         <BookItems key={item.id} item={item} Ondel={DeleteNameList} User={User} />
        )}
      </ul>
    </div>
  );
}

export default App;

Redux快速上手

入门 Redux | Redux 中文官网

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width= , initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="decrement">-</button>
    <span id="count">0</span>
    <button id="increment">+</button>
</body>
<script src="./redux.min.js"></script>
<script>
    //1、定义reducer函数
    //作用:根据不同的action对象,返回不同新的state
    //state:管理数据初始状态
    //action:对象type标记当前想要做什么修改
    function reducer(state = { count: 0 }, action) {
        //数据不可变:基于原始状态生成一个新的状态
        if (action.type === "INCRENT") {
            return { count: state.count + 1 };
        }
        if (action.type == "DELETE") {
            return { count: state.count - 1 };
        }
        return state;
    };
    //2、使用reducer函数生成store实例
    const store=Redux.createStore(reducer);
    //3、通过store实例的subscribe订阅数量变化
    //回调函数可以在每次state发生变化时自动执行
    store.subscribe(()=>{
        console.log("state变化了",store.getState());
        document.getElementById("count").innerText=store.getState().count;
    });
    //4、通过store实例的dispatch函数提交action更改状态
    const inBtn=document.getElementById('increment');
    inBtn.addEventListener("click",()=>{
        //增
        store.dispatch({
            type:"INCRENT"
        })
    });
    const Btn=document.getElementById('decrement');
    Btn.addEventListener("click",()=>{
        //增
        store.dispatch({
            type:"DELETE"
        })
    });
</script>

</html>
Redux与react
  1. 先输入命令行 npm i @reduxjs/toolkit react-redux

  2. 在src目录下面创建store然后接着创建modules和index.js,最后在modules加入相应的js模块(仓库)

  3. 第一步先将仓库模块在(modeules)文件夹下创建好(createSlice)注册好仓库名称(name)、仓库物品(initialState)、仓库物品作用(reducers)。

  4. 第二步注册好仓库在网上(configureStore),在注册网站(reducer)取好名字和对应仓库位置( counter:counterStore)

  5. 第三步开始使用首先在(react/index.js),网上找到仓库并打开(),然后拿到需要用到的地方(App.js)用到需要展示的物品用(useSelector)展示(useDispatch)用于针对物品操作

  6. 用action的payload属性获取他的方法传入的值。

  7. //账单列表相关的store
    import { createSlice } from "@reduxjs/toolkit";
    import axios from "axios";
    const BillStore=createSlice({
        name:"billstore",
        initialState:{
            billList:[]
        },
        reducers:{
            //同步修改方法
            setBillList(state,action){
                state.billList=action.payload;
            },
            //新增方法
            addBill(state,action){
                state.billList.push(action.payload);
            },
        }
    })
    
    const {setBillList,addBill}=BillStore.actions;
    const fillBillList=()=>{
        return async(dispatch)=>{
            const res=await axios.get("http://localhost:8888/ka");
            dispatch(setBillList(res.data));
        }
    }
    const addBillList=(data)=>{
        return async(dispatch)=>{
            const res=await axios.post("http://localhost:8888/ka",data);
            dispatch(addBill(res.data));
        }
    }
    export {fillBillList,addBillList};
    const reducer=BillStore.reducer;
    export default reducer;
    
    import { configureStore } from "@reduxjs/toolkit";
    import billrequred from "./Moudules/billStore"
    
    const store=configureStore({
        reducer:{
            bill:billrequred
        }
    });
    export default store;
    
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import { RouterProvider } from 'react-router-dom';
    import Roter from './Router';
    import "./theme.css"
    import { Provider } from 'react-redux';
    import store from './Store';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
        <Provider   store={store}>
            <RouterProvider router={Roter} />
        </Provider>
    );
    
    
Router 路由
什么是前端路由
  1. npm i react-router-dom

  2. 导入createBrowserRouter和RouterProvider

  3. 写入path属性和element属性

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

文件跳转
  1. 第一种使用Link,import {Link} from “react-router-dom”
  2. 跳转
  3. 第二种使用useNavigate,import {useNavigate} from “react-router-dom”
  4. const navigate=useNavigate()
  5. <button Onclick=(()=>{navigate(“/跳转页面path”)})>跳转
import { Link,useNavigate } from "react-router-dom";
const Login=()=>{
    const navigate=useNavigate();
    return (
        <div id="login">我是登录页面
        <Link to="/article">跳转到文章页面</Link>
        <button onClick={()=>{navigate("/article")}}>跳转</button>
        </div>
    );
}
export default Login
获取跳转参数
  1. 第一种方法useSearchParams,import { useSearchParams} from “react-router-dom”;
  2. 在执行跳转的页面写"/article?id=1&name=纳米"
  3. 在被跳转的页面写const SearchParams=useSearchParams(); const[params]=SearchParams.get(“参数”)
  4. 第二种useParams,import { useParams } from “react-router-dom”;
  5. 在执行跳转的页面写"/article/1001/Nami"
  6. const params=useParams();console.log(“name”,params.name,“,id”,params.id)
import { useSearchParams,useParams } from "react-router-dom";
const Article=()=>{
    //第一种方法
    // const [params]=useSearchParams();
    // const id=params.get("id");
    // const name=params.get("name");
    // console.log(id);
    // console.log(name);
    //第二种方法
    const params=useParams();
    console.log("name",params.name,",id",params.id)
    return (
        <div id="Article">文章页面</div>
    );
}
export default Article
路由嵌套
  1. 在做router配置的时候在路由属性中加入children

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  2. 然后用Outlet来渲染嵌套的路由

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    import { Outlet,Link } from "react-router-dom";
    const indexs=()=>{
        return (<div>
            我是indexs页面
            <Link to="/about">关于</Link>||
            <Link to="/details">详情</Link>
            <Outlet></Outlet>
        </div>);
    }
    export default indexs;
    
二级路由默认嵌套
  1. 将children中的path改为index设为true

  2. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  3. 将link中的to=“/demo"改为to=”

  4. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

antD-mobile主题定制

分为局部与全局

主题 - Ant Design Mobile

  1. 局部用类名来进行css编写如.className{–add-color-primary:颜色}
  2. 全局:root:root{–add-color-primary:颜色}
:root:root{
    --adm-color-primary:rgba(105,174,120);
}
/* .puple{
    --adm-color-primary:#a062d4;
} */
配置@别名路径

比如路径开始"…/page"有了@就可以"@/page"

  1. npm i @craco/craco

  2. 安装成功后创建craco.config.js文件

  3. 写入

  4.  const path=require("path");
       
       
       
       module.exports={
       
         webpack:{
       
           alias: {
       
           '@':path.resolve(__dirname,'src')
       
          }
       
         }
       
       }
       
    
  5. 修改package.json里面scrpts内容

  6. "scripts": {
    
      "start": "craco start",
    
      "build": "craco build",
    
      "test": "craco test",
    
      "eject": "react-scripts eject"
    
     }
    
  7. 然后加入jsconfig.json文件

  8. {
        "compilerOptions": {
            "baseUrl": "./",
            "paths": {
                "@/*":[
                    "src/*"
                ]
            }
        }
    }
    
高阶封装组件
//封装高价组件
//核心条款:有token正常跳转无token去登录

import { getToken } from "@/utils";
import { Navigate } from "react-router-dom";

export function AuthRoute({children}){
    const token=getToken();
    if(token){
        return <>{children}</>
    }
    else{
        return <Navigate to={'/'}></Navigate>
    }
}
useMemo
  1. useMemo用于处理复杂计算机

  2. import { useMemo, useState } from 'react'
    
    function fib (n) {
      console.log('计算函数执行了')
      if (n < 3) return 1
      return fib(n - 2) + fib(n - 1)
    }
    
    function App() {
      const [count, setCount] = useState(0)
      // 计算斐波那契之和
       const sum = fib(count)
      // 通过useMemo缓存计算结果,只有count发生变化时才重新计算
      // const sum = useMemo(() => {
      //   return fib(count)
      // }, [count])
    
      const [num, setNum] = useState(0)
    
      return (
        <>
          {sum}
          <button onClick={() => setCount(count + 1)}>+count:{count}</button>
          <button onClick={() => setNum(num + 1)}>+num:{num}</button>
        </>
      )
    }
    
    export default App
    
memo方法
  1. memo方法用于限制因为usestate数据变化造成的子组件刷新问题

  2. import { memo, useMemo, useState } from 'react'
    
    
    const MenoSon=memo(
      function Son(){
        console.log("我是子组件,我重新渲染了");
        return <div>thi is Son</div>
      }
    )
    function Son(){
      console.log("我是子组件,我重新渲染了");
      return <div>thi is Son</div>
    }
    function App() {
      const [count,setCount]=useState(0);
      return (
        <>
         <button onClick={()=>setCount(count+1)}>+</button>
            <Son></Son>
         {/* <MenoSon></MenoSon> */}
        </>
      )
    }
    
    export default App
    
useCallBack组件
  1. 用于阻止事件重新渲染

  2. import { memo, useCallback, useMemo, useState } from 'react'
    
    
    const MenoSon=memo(
      function Son({count}){
        console.log("子组件重新渲染 ");
        return <input type='text' onChange={(e)=>{count(e.target.value)}}></input>
      }
    )
    function App() {
      const [count,setCount]=useState(0);
      const valueSet=useCallback((value)=>{
        console.log(value);
      },[]);
      return (
        <>
         <button onClick={()=>setCount(count+1)}>+</button>
          <MenoSon count={valueSet}></MenoSon> 
        </>
      )
    }
    
    export default App
    
useReducre
  1. const [state,dispatch]=useReducre(reducre,0);

  2. 主要是针对与复杂的赋值

  3. import { useReducer } from "react";
    
    function reducerl(state, action) {
      switch (action.type) {
        case "INC":
          return state + 1;
        case "DEC":
          return state - 1;
        default:
          return state;
      }
    }
    function App() {
      const [state, dispatclh] = useReducer(reducerl, 0);
      return (
        <div className="App">
          <button onClick={()=>dispatclh({type:"DEC"})}>-</button>
          this APP is
          {state}
          <button onClick={()=>dispatclh({type:"INC"})}>+</button>
        </div>
      );
    }
    
    export default App;
    
    
props的比较机制
  1. 对于props的比较,进行的是‘浅比较’,底层使用 Object.is 进行比较,针对于对象数据类型,只会对比俩次的引用是否相等,如果不相等就会重新渲染,React并不关心对象中的具体属性

  2. import { memo, useMemo, useState } from 'react'
    
    
    const MenoSon=memo(
      function Son({count}){
        console.log("我是子组件,我重新渲染了");
        return <div>thi is Son {count}</div>
      }
    )
    function App() {
      const [count,setCount]=useState(0);
      // const [list,setList]=useState([0]);
      ///const listcopy=[1,2,3];
      const list=useMemo(()=>{
        return [1,2,3];
      },[])
      return (
        <>
         <button onClick={()=>setCount(count+1)}>+</button>
          <MenoSon count={list}></MenoSon> 
        </>
      )
    }
    
    export default App
    
useImperativeHandle与forwardRef
  1. 将子节点的方法暴露给父节点

  2. import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
    
    //子组件
    const Son=forwardRef((props,ref)=>{
      const inputRef=useRef(null);
      const forcusHandler=()=>{
        inputRef.current.focus()
      }
      //把聚焦方法暴露出去
      useImperativeHandle(ref,()=>{
        return {
          //暴露方法
          forcusHandler
        }
      })
      return <input type='text' ref={inputRef}></input>
    })
    
    function App() {
      const sonRef=useRef(null);
      const focusHandle=()=>{
          console.log(sonRef.current);
          sonRef.current.forcusHandler();
      }
      return (
        <>
          <Son ref={sonRef}></Son>
          <button onClick={focusHandle}>focus</button>
        </>
      )
    }
    
    export default App
    
useRef与forwardRef
  1. 允许组件使用ref将一个DOM节点暴露给父组件

  2. import { forwardRef, useRef } from "react";
    
    const Son = forwardRef((props, ref) => {
      return <input type="text" ref={ref}></input>;
    });
    
    function App() {
      const sonRef = useRef(null);
      const showRef = () => {
        console.log(sonRef);
        sonRef.current.focus();
      };
      return (
        <>
          <button onClick={showRef}>+</button>
          <Son ref={sonRef}></Son>
        </>
      );
    }
    
    export default App;
    
    
Scss文件
  1. 安装npm i -d sass
  2. 然后进行绑定就行了
normalize.css
  1. Normalize.css简介及详解、使用-CSDN博客
  2. npm install normalize.css 安装指令
  3. 在入口文件index.js导入import “normalize.css”
useLocation

获取当前路由名称

LocalStorage

用于存储数据不被页面刷新

Antd组件
  1. 组件总览 - Ant Design
  2. npm i antd -save
打包优化
配置路由懒加载

路由懒加载主要是优化项目首次打开时间

  1. 导入lazy函数
  2. 在内置react使用suspense组件
包体积分析
  1. 先安装包 npm i source-map-explorer
  2. 在package.json里面配置"analyze":“source-map-explorer ‘build/static/js/*.js’”

类组件

简单示例
import { Component, forwardRef, useImperativeHandle, useRef, useState } from 'react'


class Counts extends Component{
  state={
    count:0
  };
  setCount=()=>{
    this.setState({
      count:this.state.count+1
    })
  }
  render(){
    return <button onClick={this.setCount}>{this.state.count}</button>
  }
}

function App() {
  
  return (
    <>
      <Counts></Counts>
    </>
  )
}

export default App
生命周期

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

import { Component, forwardRef, useImperativeHandle, useRef, useState } from 'react'


class Counts extends Component{
  //声明周期函数
  //组件渲染完毕执行一次 发送网络请求
  componentDidMount(){
    console.log("组件渲染完毕 开始发送请求");
    //定时器开始运行
    this.timer=setInterval(()=>{
      console.log('定时器运行中');
    },1000);
  }
  //组件卸载时执行
  //一般用于清理定时器和事件绑定
  componentWillUnmount(){
    console.log("组件被卸载了");
    clearInterval(this.timer);
  }
  state={
    count:0
  };
  setCount=()=>{
    this.setState({
      count:this.state.count+1
    })
  }
  render(){
    return <button onClick={this.setCount}>{this.state.count}</button>
  }
}

function App() {
  const [show,setShow]=useState(true);
  return (
    <>
     {show&&<Counts></Counts>}
     <button onClick={()=>setShow(!show)}>摧毁</button>
    </>
  )
}

export default App
父子通讯
  1. 子组件向父组件传值用函数赋值的方法

  2. 父组件向子组件传值直接传prop

  3. import { Component, forwardRef, useImperativeHandle, useRef, useState } from 'react'
    
    //父组件定义
    class Father extends Component{
     state={
      message:"this a exmal from you father"
     }
    FromFatherFunction=(fromSonValue)=>{
        console.log("这是fromfatherfunction","fromSonValue的值",fromSonValue);
     };
      render(){
        return  <><p>我来自父组件</p><Son msd={this.state.message} OnMsg={this.FromFatherFunction}></Son></>
      }
    }
    //子组件定义
    class Son extends Component{
    
      render(){
        return <><p>我来自子组件</p>{this.props.msd}
        <button onClick={()=>{this.props.OnMsg("i am Son")}}>点击</button></>
      }
    }
    
    function App() {
     
      return (
        <>
        <Father></Father>
        </>
      )
    }
    
    export default App
    

zustand

简单使用
  1. 安装 yarn add zustand

  2. import {create} from "zustand"
    
    const useStore=create((set)=>{
      return{
        count:0,
        inc:()=>{
         set((state)=>({count:state.count+1}))
        }
      }
    });
    function App() {
     const {count,inc}=useStore();
      return (
        <>
        <button onClick={inc}>{count}</button>
        </>
      )
    }
    
    export default App
    
异步使用
import {create} from "zustand"
import {useEffect} from "react"

const URL='http://geek.itheima.net/v1_0/channels';

const CreateCountStore=(set)=>{
  return {
    count:0,
    inc:()=>{
      set((state)=>({count:state.count+1}))
    }
  }
}

const CreateChannelsStore=(set)=>{
  return{
    channlesList:[],
    fetchGetList:async()=>{
      const res=await fetch(URL);
      const jsonRes=await res.json();
      console.log(jsonRes);
      set({channlesList:jsonRes.data.channels});
    }
  }
}
const useStore=create((...a)=>{
 return{
  ...CreateChannelsStore(...a),
  ...CreateCountStore(...a)
 }
});
function App() {
 const {count,inc,fetchGetList,channlesList}=useStore();
 useEffect(()=>{
  fetchGetList();
 },[fetchGetList]);
  return (
    <>
    <button onClick={inc}>{count}</button>
    <ul>
      {channlesList.map((item)=>{return <li >{item.name}</li>})}
    </ul>
    </>
  )
}

export default App
切片编程

分成与redux一样的结构

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

vite+react+ts

前言

vite在线文档:开始 | Vite 官方中文文档 (vitejs.cn)

vite创建项目指令:npm create vite@latest react-vite-demo – --template react-ts
romFatherFunction=(fromSonValue)=>{
console.log(“这是fromfatherfunction”,“fromSonValue的值”,fromSonValue);
};
render(){
return <>

我来自父组件

</>
}
}
//子组件定义
class Son extends Component{
 render(){
   return <><p>我来自子组件</p>{this.props.msd}
   <button onClick={()=>{this.props.OnMsg("i am Son")}}>点击</button></>
 }

}

function App() {

 return (
   <>
   <Father></Father>
   </>
 )

}

export default App


## zustand

#### 简单使用

1. 安装 yarn add zustand

2. ```js
import {create} from "zustand"

const useStore=create((set)=>{
  return{
    count:0,
    inc:()=>{
     set((state)=>({count:state.count+1}))
    }
  }
});
function App() {
 const {count,inc}=useStore();
  return (
    <>
    <button onClick={inc}>{count}</button>
    </>
  )
}

export default App
异步使用
import {create} from "zustand"
import {useEffect} from "react"

const URL='http://geek.itheima.net/v1_0/channels';

const CreateCountStore=(set)=>{
  return {
    count:0,
    inc:()=>{
      set((state)=>({count:state.count+1}))
    }
  }
}

const CreateChannelsStore=(set)=>{
  return{
    channlesList:[],
    fetchGetList:async()=>{
      const res=await fetch(URL);
      const jsonRes=await res.json();
      console.log(jsonRes);
      set({channlesList:jsonRes.data.channels});
    }
  }
}
const useStore=create((...a)=>{
 return{
  ...CreateChannelsStore(...a),
  ...CreateCountStore(...a)
 }
});
function App() {
 const {count,inc,fetchGetList,channlesList}=useStore();
 useEffect(()=>{
  fetchGetList();
 },[fetchGetList]);
  return (
    <>
    <button onClick={inc}>{count}</button>
    <ul>
      {channlesList.map((item)=>{return <li >{item.name}</li>})}
    </ul>
    </>
  )
}

export default App
切片编程

分成与redux一样的结构

[外链图片转存中…(img-1NPG0lDF-1723444851992)]

vite+react+ts

前言

vite在线文档:开始 | Vite 官方中文文档 (vitejs.cn)

vite创建项目指令:npm create vite@latest react-vite-demo – --template react-ts

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

特爱C#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值