1:第一个useState

用来声明和修改数据
import  {useState} from  "react"
let  [num,setNum] = useState(0);

使用: {num}
修改:{setNum}
注意细节
1:useState是异步的;
2:useState(()=>state);
useState的数据 修改以后马上获取  可以使用回调

2:第二个useEffect 副作用函数

主要用来模拟生命周期 和数据监听
生命周期: 三个阶段   挂载 更新  销毁    
 useEffect有两个参数  第一个函数  第二个依赖项
 如果依赖项不填 数据更新的时候都会触发
 
 useEffect(() => {
    console.log("页面加载");
    console.log("实时的num为"+num);
  },[num]);

  useEffect(() => {
    return () => {
      console.log("页面销毁");
    };
  },[]);
  let add = () => {
    setnum(num + 1);
  };

3:第三个hook useRef

import React, {useRef } from "react";

//声明
  let usernameInput = useRef();
  let userageInput = useRef();
  //使用
   <div>
        <div>
          姓名 <input ref={usernameInput} />
        </div>
        <div>
          年龄 <input ref={userageInput} />
        </div>
      </div>
      //取值
      usernameInput.current.value;
      //赋值
      usernameInput.current.value = item.username;
     userageInput.current.value = item.userage;

4:useContext 公共的上下文关系对象(跨层级的组件通信)

import React,{useContext} from 'react'
import NumContext from '../context/NumContext'

export default function Child2() {
    let context = useContext(NumContext)
  return (
    <div>Child2
        公共的数据为{context.num}
    </div>
  )
}

5: useReducer 分离和规范useSetate的写法

//之前 都是在一个方法里面
  //     const [list, setlist] = useState([]);
  //     //新增数据
  //    // setlist([...list,item])
  //    // setlist(list.filter(item=>item.id!==id));
  //    // setlist(list.map(item=>{
  //    //  if(item.id ===id){ item.name="abc"}
  //    //     return item
  //    //  }))


分离以后
function reducer(state, action) {
  //state表示数据(状态)  action 描述的对象
  switch (action.type) {
    case "init":
        return action.payload;
    case "add":
      return [...state, action.payload];
    case  "del":
        return  state.filter(item=>item.id!==action.payload)  
    default:
      return state;
  }
}
//使用
export default function UseReducer() {
  const [state, dispatch] = useReducer(reducer, []);

  useEffect(() => { //页面加载成功

        dispatch({
            type:"init",
            payload:[{id:1},{id:2},{id:3}]
        })
  
  }, [])
  let add = function () {
    //调用接口  成功以后同步页面效果
    dispatch({
      type: "add",
      payload: { id: 3 },
    });
  };
  let delById = (payload) => {
    dispatch({
      type: "del",
      payload,
    });
  };

  return (
    <div>
      <button onClick={add}>新增</button>
      <div className="tr">
        <div className="td">编号</div>
        <div className="td">操作</div>
      </div>
      {state.map((item) => {
        return (
          <div className="tr" key={item.id}>
            <div className="td">{item.id}</div>
            <div
              className="td"
              onClick={() => {
                delById(item.id);
              }}
            >
              删除
            </div>
          </div>
        );
      })}
    </div>
  );
}

6: useCallBack

父组件
import React,{useState} from 'react'
import Child3 from '../components/Child3'

export default function UseCallBack() {

    const [num, setnum] = useState(10);

  return (
    <div>UseCallBack
        <div>显示数据{num}<button onClick={()=>{
            setnum(num+1);
        }}>修改数据</button> </div>
        <hr/>
        <Child3></Child3>
    </div>
  )
}

子组件
import React from 'react'

export default function Child3() {
    console.log("加载child3");
  return (
    <div>Child3</div>
  )
}

问题:父组件中的数据变化了  子组件都会重新渲染   在类组件中shouldComponentUpdate 可以解决 return false

hooks中解决 :缓存组件(keep-alive)
import React,{memo} from 'react'

 function Child3() {
    console.log("加载child3");
  return (
    <div>Child3</div>
  )
}

export default memo(Child3);


import React, { useCallback, useState } from "react";
import Child3 from "../components/Child3";

export default function UseCallBack() {
  const [num, setnum] = useState(10);
  const [n, setn] = useState(1)

  let  fn  = useCallback(()=>{
            console.log(n+"发生了改变");
  },[n]);

  return (
    <div>
      UseCallBack
      <div>
        显示数据{num}
        <button
          onClick={() => {
            setnum(num + 1);
          }}
        >
          修改数据
        </button>{" "}
      </div>
      <div>
        数据n为{n}
        <button onClick={()=>{
            setn(n+1);
        }}>修改n</button>
      </div>
      <hr />
      <Child3 fn={fn}></Child3>
    </div>
  );
}

7:useMemo 计算属性 根据指定的值的变化 生成新的值

import React, { useMemo, useState } from "react";

export default function UseMemo() {
  const [num, setnum] = useState(10);
  const [price, setprice] = useState(88);

  const [n, setn] = useState(1);

  let fn1  = function(){
    console.log("开始计算");
    return  num * price;
  }

 let total= useMemo(() =>{
    console.log("我也开始计算")
    return  num*price
 } , [num,price])

  return (
    <div>
        <div>
            n为{n}
            <button onClick={()=>{
                setn(n+1);  
            }}>修改n</button>
        </div>
      UseMemo
      <div>
        数量{" "}
        <input
          value={num}
          onChange={(e) => {
            setnum(e.target.value);
          }}
        />{" "}
      </div>
      <div>
        价格{" "}
        <input
          value={price}
          onChange={(e) => {
            setprice(e.target.value);
          }}
        />{" "}
      </div>
      总价{price*num}
      <div>函数取总价 {fn1()}</div>
      <div>统计{total}</div>
    </div>
  );
}

8:useRef

1:标记标签名称  想到了ref 方便组件内部使用
2:如果父组件想获取子组件的实例 比如子组件自身提供暴露的方法 forwarRef  

import React,{useRef} from 'react'

export default function Child4({setMsg}) {
    const msgInput = useRef();
  return (
    <div>Child4

        <div>内容:<input ref={msgInput}/>
            <button onClick={()=>{
                setMsg(msgInput.current.value);
            }}>给父组件</button>
        </div>
    </div>
  )
}

3:useImperativeHandle 暴露子组件的方法给父组件 配合forwardRef来使用
import React,{useRef,forwardRef,useImperativeHandle} from 'react'

 function Child4({setMsg},ref) {

    const msgInput = useRef();


  useImperativeHandle(ref, () => ({
    getMsg: () => { //暴露子组件的方法给 父组件
      return  msgInput.current.value;
    },
    setMsg:(msg)=>{
        msgInput.current.value = msg;
    }
  }));

  return (
    <div>Child4
        <div>内容:<input ref={msgInput}/>
            <button onClick={()=>{
                setMsg(msgInput.current.value);
            }}>给父组件</button>
        </div>
    </div>
  )
}
export default forwardRef(Child4);



使用;
  return (
    <div>
        <button onClick={()=>{
            child4.current.setMsg("来自爸爸的爱");
        }}>设置子组件的内容</button>
        UseRef
        显示子组件的值{msg}
        <button onClick={()=>{
           setMsg(child4.current.getMsg());

        }}>我要获取子组件的内容</button>

        <Child4 setMsg={setMsg} ref={child4}></Child4>
    </div>
  )

9:useEffect 的函数会在组件渲染到屏幕之后执行 :useLayoutEffect则是在DOM结构更新后、渲染前执行,相当于有一个防抖效果


import { useLayoutEffect,useEffect, useState } from "react";

export default function App() {
    const [value, setValue] = useState(0);
    useLayoutEffect(() => {
      if (value === 0) {
        setValue(10 + Math.random() * 200);
      }
    }, [value]);
    // console.log("render", value);
    return (
      <div onClick={() => setValue(0)}>value: {value}</div>
    );
  }


//hooks  ahooks
//redux  mobx  RTK
//antd -pro  antd - mobile
//React-native  taro 

10:ahooks 文档

https://ahooks.gitee.io/zh-CN/hooks/use-request/index

数据请求的例子
import React, { useEffect, useState } from "react";
import { useRequest } from "ahooks";
import { userQuery, userDelById, userAdd } from "../service/userService";

export default function UseRequest() {
  const [username, setUsername] = useState("");
  const [userage, setUserage] = useState("");

  //页面加载的方法
  let { data, run: GetList } = useRequest(userQuery, {
    manual: true, //手动触发
    debounceWait: 500, //表示两秒内只触发一次
  });
  useEffect(() => {
    GetList({}); //页面加载  触发
  }, []);

  //删除的方法
  let { run: delListById } = useRequest(userDelById, {
    manual: true, //表示手动触发
    onSuccess: () => {
      GetList({}); //获取最新的数据
    },
  });

  //新增的方法
  let { run: addList } = useRequest(userAdd, {
    manual: true, //表示手动触发
    onSuccess: () => {
      GetList({}); //获取最新的数据
    },
  });

  return (
    <div>
      <div>
        姓名{" "}
        <input
          value={username}
          onChange={(e) => {
            setUsername(e.target.value);
          }}
        />{" "}
      </div>
      <div>
        年龄{" "}
        <input
          value={userage}
          onChange={(e) => {
            setUserage(e.target.value);
          }}
        />{" "}
      </div>
      <button
        onClick={() => {
          addList({ username, userage });
        }}
      >
        新增
      </button>
      <hr />
      <input
        placeholder="用户名查询"
        onChange={(e) => {
          GetList({ username_like: e.target.value }); //表示根据用户名进行查询
        }}
      />
      <div className="tr">
        <div className="td">编号</div>
        <div className="td">姓名</div>
        <div className="td">年龄</div>
        <div className="td">操作</div>
      </div>

      {data?.data.map((item) => {
        return (
          <div className="tr" key={item.id}>
            <div className="td">{item.id}</div>
            <div className="td">{item.username}</div>
            <div className="td">{item.userage}</div>
            <div
              className="td"
              onClick={() => {
                delListById(item.id);
              }}
            >
              删除
            </div>
          </div>
        );
      })}
    </div>
  );
}


页面同步更新效果
import React, { useEffect, useState } from "react";
import { useRequest, useSetState } from "ahooks";
import { userQuery, userDelById, userAdd } from "../service/userService";

export default function UseRequest() {
  const [username, setUsername] = useState("");
  const [userage, setUserage] = useState("");
  const [list, setList] = useState([]);

  const [info, setinfo] = useSetState({
    username: "leson",
    userage: 18,
  });

  //页面加载的方法
  let { run: GetList } = useRequest(userQuery, {
    manual: true, //手动触发
    debounceWait: 500, //表示两秒内只触发一次
    onSuccess: (res) => {
      setList(res.data);
    },
  });
  useEffect(() => {
    GetList({}); //页面加载  触发
  }, []);

  //删除的方法
  let { run: delListById } = useRequest(userDelById, {
    manual: true, //表示手动触发
    throttleWait: 3000, //节流

    onSuccess: (res, params) => {
      //     console.log(params);
      //   GetList({}); //获取最新的数据
      setList(list.filter((item) => item.id !== params[0]));
    },
  });

  //新增的方法
  let { run: addList } = useRequest(userAdd, {
    manual: true, //表示手动触发
    throttleWait: 1000, //节流
    onSuccess: (res, params) => {
      //     console.log(res.data);
      //     console.log(params);
      //   GetList({}); //获取最新的数据
      setList([...list, res.data]);
    },
  });

  return (
    <div>
      <div>
        姓名{" "}
        <input
          value={username}
          onChange={(e) => {
            setUsername(e.target.value);
          }}
        />{" "}
      </div>
      <div>
        年龄{" "}
        <input
          value={userage}
          onChange={(e) => {
            setUserage(e.target.value);
          }}
        />{" "}
      </div>
      <button
        onClick={() => {
          addList({ username, userage });
        }}
      >
        新增
      </button>
      <hr />
      <input
        placeholder="用户名查询"
        onChange={(e) => {
          GetList({ username_like: e.target.value }); //表示根据用户名进行查询
        }}
      />
      <div className="tr">
        <div className="td">编号</div>
        <div className="td">姓名</div>
        <div className="td">年龄</div>
        <div className="td">操作</div>
      </div>

      {list.map((item) => {
        return (
          <div className="tr" key={item.id}>
            <div className="td">{item.id}</div>
            <div className="td">{item.username}</div>
            <div className="td">{item.userage}</div>
            <div
              className="td"
              onClick={() => {
                delListById(item.id);
              }}
            >
              删除
            </div>
          </div>
        );
      })}

      <div>
        对象的更新 姓名{info.username} 年龄{info.userage}
        <button
          onClick={() => {
            setinfo({ userage: 100 });
          }}
        >
          更新
        </button>
      </div>
    </div>
  );
}