useReducer
useReducer 是 React Hooks 中的一个函数,用于管理组件的状态。它类似于 useState,但提供了更复杂的状态逻辑处理能力。 接受一个 reducer 函数和初始状态作为参数,并返回当前状态和 dispatch 函数。
使用 useReducer 的基本流程如下:
- 定义一个 reducer 函数,接受当前状态和 action 参数,并根据 action 的类型来更新状态。
- 在组件中使用 useReducer,传入 reducer 函数和初始状态,得到当前状态和 dispatch 函数。
- 在需要更新状态的地方,调用 dispatch 函数并传入对应的 action,从而触发 reducer 函数更新状态。
javascript
const reduce = (state, action) => {
switch (action.type) {
case "add":
return state + 1;
case "dsc":
return state - 1;
case "update":
return action.payload
default:
break;
}
};
export default function App() {
const [state, dispatch] = useReducer(reduce,0)
return (
<div>
<button
onClick={() => {
dispatch({ type: "add" });
}}
>
+
</button>
{state}
<button
onClick={() => {
dispatch({ type: "dsc" });
}}
>
-
</button>
<button
onClick={() => {
dispatch({ type: "update", payload:1000 });
}}
>
update
</button>
</div>
);
}
useMemo
useMemo
是React Hooks中的一个函数,用于优化性能。它接收一个函数和一个依赖数组作为参数,返回一个memoized(记忆化)的值。当依赖数组中的值发生变化时,useMemo
会重新计算并返回新的值,否则会直接返回上一次计算的结果。
useMemo
的作用是避免在每次渲染时都重新计算相同的值,尤其是在计算量较大的情况下,可以显著提高性能。常见的用法包括计算一些昂贵的值、避免不必要的重复渲染等。
javascript
// useMemo
// 缓存: 消耗非常大的计算
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 [count1, setCount1] = useState(0);
const result = useMemo(() => {
// 返回计算得到的结果
return fib(count1);
}, [count1]);
// const result = fib(count1)
const [count2, setCount2] = useState(0);
console.log("组件重新渲染了");
return (
<div className="App">
this is app
<button onClick={() => setCount1(count1 + 1)}>
change count1: {count1}
</button>
<button onClick={() => setCount2(count2 + 1)}>
change count2: {count2}
</button>
{result}
</div>
);
}
export default App;
React memo的使用
作用:允许组件在 Props没有改变 的情况下跳过渲染
React组件默认的渲染机制:只要父组件重新渲染子组件就会重新渲染
基本语法:
javascript
import React from "react";
import { useState, memo } from "react";
const MemoZi = memo(function Zi() {
console.log("我是子组件");
return <div>this is Zi commponent</div>;
});
export default function App() {
const [num, setNum] = useState(0);
return (
<div>
App
<MemoZi />
{num}
<button
onClick={() => {
setNum(num + 1);
}}
>
+1
</button>
</div>
);
}
useCallback
是 React Hooks 中的一个函数,用于优化性能和避免不必要的重新渲染。
当一个组件使用 useCallback 包裹一个函数时,它会返回一个记忆化的版本的函数。这意味着只有当依赖项发生变化时,才会返回新的函数。这可以避免在每次渲染时都创建新的函数实例,从而减少不必要的内存消耗和重新渲染。
useCallback 接受两个参数:第一个参数是一个函数,第二个参数是一个依赖项数组。当依赖项数组中的任何一个值发生变化时,useCallback 会返回一个新的函数。如果依赖项数组为空,useCallback 会在每次渲染时都返回同一个函数。
javascript
// useCallback
import { memo, useCallback, useState } from "react";
const Input = memo(function Input({ onChange }) {
console.log("子组件重新渲染了");
return <input type="text" onChange={(e) => onChange(e.target.value)} />;
});
function App() {
// 传给子组件的函数
const changeHandler = useCallback((value) => console.log(value), []);
// 触发父组件重新渲染的函数
const [count, setCount] = useState(0);
return (
<div className="App">
{/* 把函数作为prop传给子组件 */}
<Input onChange={changeHandler} />
<button onClick={() => setCount(count + 1)}>{count}</button>
</div>
);
}
export default App;
forwardRef
forwardRef
是 React 中的一个高级函数,用于在函数组件中转发(forward)refs。在 React 中,refs 是用来引用 DOM 元素或类组件实例的对象,它们通常在类组件中使用。但是在函数组件中使用 refs 可能会有一些限制,特别是在组件包裹或嵌套的情况下。forwardRef
的目的就是解决这些问题。
当使用 forwardRef
包裹函数组件时,它可以将 ref 透传给函数组件内部的某个子组件,从而允许函数组件访问这个 ref。就可以在函数组件中使用 ref 来引用子组件或 DOM 元素。
以下是 forwardRef
的基本用法:
javascript
import React from "react";
import { useRef, forwardRef } from "react";
const Zi = forwardRef((props,ref)=>{
return (
<input type="text" ref={ref} />
)
})
export default function App() {
const r = useRef(null);
const getR = () => {
console.log(r);
};
return (
<div>
<Zi ref={r} />
<button onClick={getR}>click</button>
</div>
);
}