useState 状态钩子
纯函数组件没有状态,该钩子为函数组件引入state,并进行数据操作
import { useState } from "react";
export default function FunctionComponent(props) {
const [data, setData] = useState(0);
const addOption = () => {
setData(data + 1);
};
return (
<>
<div>{data}</div>
<button onClick={addOption}>add </button>
</>
);
}
useEffect 副作用钩子 (异步执行)
用于在函数组件中进行 接口请求,订阅,监听等操作。模拟类组件中的生命周期(componentDidMount,componentDidUpdate,componentWillUnmount三个函数的组合)
// 接受两个参数,1: 异步操作函数 2:参数是一个数组
import React, { useState, useEffect } from "react";
export function FunctionComponent(props) {
const [data, setData] = useState(0);
// 第二个参数为空 每次渲染都会执行
useEffect(() => {
setData({
data: data + 0,
});
return () => {
// 卸载之后执行
};
});
// 第二个参数为空数组 组件挂载后,运行一下
useEffect(() => {
// 相当于 componentDidMount,componentDidUpdate,componentWillUnmount
return () => {
// 卸载之后执行
};
}, []);
// 第二个参数 有参数 ,监听参数的改变
useEffect(() => {
return () => {
// 卸载之后执行
};
}, [data]);
return <div>{data}</div>;
}
useContext 共享状态钩子
跨越组件层级直接传递变量,实现数据共享
import { useState, useContext, createContext } from "react";
const CountContext = createContext(0);
export default function FunctionComponent(props) {
const [count, setCount] = useState(0);
function addCount() {
setCount(count + 1);
}
return (
<>
<div>{count}</div>
<button onClick={addCount}>点击一下</button>
{/* 通过value传值 外面要包裹 xxxContext.Provider*/}{" "}
<CountContext.Provider value={count}>
<Child />
</CountContext.Provider>
</>
);
}
const Child = () => {
// 获取数据
const count = useContext(CountContext);
return <div>子组件{count}</div>;
};
useReducer
存储和更新数据 组件传参
import { useEffect, useReducer } from "react";
function setName(state = [], action) {
switch (action.type) {
case "INIT":
return [...action.payload];
case "REPALCE":
return [...action.payload];
default:
return state;
}
}
export default function FunctionComponent(props) {
const [nameList, dispath] = useReducer(setName, []);
useEffect(() => {
dispath({ type: "INIT", payload: ["小红", "小王"] });
}, []);
return (
<div>
<NameList
nameList={nameList}
setName={(parms) => dispath({ type: "REPALCE", payload: parms })}
></NameList>
</div>
);
}
function NameList({ nameList, setName }) {
const deleteItem = (index) => {
const tem = [...nameList];
tem.splice(index, 1);
setName(tem);
};
return (
<div>
{nameList.map((item, index) => {
return (
<div key={item} onClick={(index) => deleteItem(index)}>
{item}
</div>
);
})}
</div>
);
}
useMemo 缓存
在react父组件改变,自组件会保持更新。比较不合理
import{ useState , useMemo} from "react"
function fn (count){
console.log("重新渲染了")
return count+"new"
}
function App(){
const [count,setCount]=useState(0)
const [num,setNum]=useState(0)
//无论是count或者num改变,fn函数都会渲染
// const result=fn(count)
// 只有count改变的时候,才会渲染
const result=useMemo(()=>fn(count),[count])
return (
{result}
<button onClick={()=>setCount(count++)}>+</button>
<button onClick={()=>setnum(num++)}>+</button>
)
}
export default App
React.memo
组件在props没有改变时候,不再渲染
注:memo的缓存只能缓存简单类型,不能缓存引用类型,要想缓存引用类型,需要使用useMemo进行缓存
import{ useState , memo} from "react"
function Son (){
console.log("Son重新渲染了")
return "SON"
}
const SonMemo=memo(function Son ({count}){
console.log("SonMemo重新渲染了")
return count+"new"
}
)
function App(){
const [count,setCount]=useState(0)
const [num,setNum]=useState(0)
const list=[1,2,3]
return (
//无论是count或者num改变,Son都会渲染
<Son />
// 只有count改变的时候,才会渲染
<SonMemo count={count} list={list}/>
<button onClick={()=>setCount(count++)}>+</button>
<button onClick={()=>setnum(num++)}>+</button>
)
}
export default App
useCallback 渲染性能优化 (缓存函数本身)
import{ useState , memo ,useCallBack} from "react"
const SonMemo=memo(function Son ({handleChange}){
console.log("SonMemo重新渲染了")
handleChange(6666)
return count+"new"
}
)
function App(){
const [count,setCount]=useState(0)
// // 每次父组件改变,自组件都会更新渲染
// function handleChange(num){
// console.log(num)
// }
// 参数1:回调函数 ,参数2 :依赖数组,依赖数组变化,函数变化。依赖数字为空,表示函数永不变化
const handleChange =useCallBack((num)=>{
console.log(num )
},[])
return (
<SonMemo count={count} handleChange={handleChange} />
<button onClick={()=>setCount(count++)}>+</button>
<button onClick={()=>setnum(num++)}>+</button>
)
}
export default App
React.forwardRef
import {forwardRef} from "react"
import { useRef } from "react";
const Son=()=>{
return <div>Son</div>
}
const SonFor=forwardRef((props,ref)=>{
return <div ref={ref}>SonFor</div>
})
function App() {
const sonRef=useRef(null)
const sonForRef=useRef(null)
function handleGetRef(){
// 打印为空
console.log(sonRef.current)
// 可以正常打印
console.log(sonForRef.current)
}
return (
<Son ref={sonRef}/>
<SonFor ref={sonForRef}/>
<button onClick={handleGetRef}>获取ref</button>
)
}
export default App;
useImperativeHandle
暴露自组件的方法给父组件
import { forwardRef, useImperativeHandle } from "react"
import { useRef } from "react";
const SonFor = forwardRef((props, ref) => {
const divRef = useRef(null)
function getRef() {
console.log(divRef.current)
}
useImperativeHandle(ref,()=>{
return {
getRef
}
})
return <div ref={divRef}>SonFor</div>
})
function App() {
const sonForRef = useRef(null)
function handleGetRef() {
// 可以正常打印
console.log(sonForRef.current)
}
return (
<SonFor ref={sonForRef}/>
<button onClick={handleGetRef}>获取ref</button>
)
}
export default App;
自定义Hook
import React, { useState, useEffect } from "react";
export default function ClassConponent(props) {
return <div>{useClick().toLocaleTimeString()}</div>;
}
// 自定义hook ,要use开头,
function useClick() {
const [date, setData] = useState(new Date());
useEffect(() => {
const timer = setInterval(() => {
setData(new Date());
}, 10000);
return () => clearInterval(timer);
}, []);
return date;
}