React 基礎(chǔ)鞏固(四十四)——其他Hooks(useContext、useReducer、useCallback)
一、useContext的使用
在類組件開發(fā)時,我們通過 類名.contextType = MyContext
的方式,在類中獲取context,多個Context或者在函數(shù)式組件中通過MyContext.Consumer
方式共享context:
import React, { memo } from 'react'
import { UserContext, ThemeContext } from './context'
export default memo(function App() {
// 使用Context
return (
<div>
<UserContext.Consumer>
{
value => {
return (
<h2>
<ThemeContext.Consumer>
{
value => {
<span></span>
}
}
</ThemeContext.Consumer>
</h2>
)
}
}
</UserContext.Consumer>
</div>
)
})
可以看到,當(dāng)我們需要使用多個Context時,存在大量繁瑣的嵌套代碼;而Context Hook能夠讓我們通過Hook直接獲取某個Context的值,如下:
import React, { memo, useContext } from "react";
import { ThemeContext, UserContext } from "./context";
export default memo(function App() {
// 使用Context
const user = useContext(UserContext);
const theme = useContext(ThemeContext);
return (
<div>
<h2>
User: {user.name} - {user.age}
</h2>
<h2>
Theme: {theme.color} - {theme.size}
</h2>
</div>
);
});
可以看到,Context Hook僅用了兩行代碼就替代了上面繁雜的嵌套代碼,十分高效簡潔。
二、useReducer的使用
useReducer是useState的一種替代方案,當(dāng)state的處理邏輯比較復(fù)雜,可以使用useReducer來進(jìn)行拆分,或者當(dāng)修改state時需要依賴之前的state時,也可以使用useReducer。
useReducer使用的場景非常少,通常用于需要統(tǒng)一管理、修改多個數(shù)據(jù)的場景。例如,當(dāng)我們需要對多個數(shù)據(jù)進(jìn)行統(tǒng)一處理時,若采用useState,則需要多次定義,而reducer可以對其進(jìn)行統(tǒng)一定義、修改:
import React, { memo, useReducer, useState } from "react";
function reducer(state, action) {
switch (action.type) {
case "increment":
return { ...state, counter: state.counter + 1 };
case "decrement":
return { ...state, counter: state.counter - 1 };
case "add_number":
return { ...state, counter: state.counter + action.num };
case "sub_number":
return { ...state, counter: state.counter - action.num };
default:
return state;
}
}
export default memo(function App() {
// const [count, setCount] = useState(0);
// const [user, setUser] = useState(0);
// const [list, setList] = useState(0);
const [state, dispatch] = useReducer(reducer, {
counter: 0,
user: {},
list: [],
});
return (
<div>
{/* <h2>當(dāng)前計數(shù):{count}</h2>
<button onClick={(e) => setCount(count + 1)}>+1</button>
<button onClick={(e) => setCount(count - 1)}>-1</button>
<button onClick={(e) => setCount(count + 5)}>+5</button>
<button onClick={(e) => setCount(count - 5)}>-5</button>
<button onClick={(e) => setCount(count + 100)}>+100</button> */}
<h2>當(dāng)前計數(shù):{state.counter}</h2>
<button onClick={(e) => dispatch({ type: "increment" })}>+1</button>
<button onClick={(e) => dispatch({ type: "decrement" })}>-1</button>
<button onClick={(e) => dispatch({ type: "add_number", num: 5 })}>
+5
</button>
<button onClick={(e) => dispatch({ type: "sub_number", num: 5 })}>
-5
</button>
<button onClick={(e) => dispatch({ type: "add_number", num: 100 })}>
+100
</button>
</div>
);
});
三、useCallback的使用
useCallback實際的目的是為了進(jìn)行性能優(yōu)化,useCallback會返回一個函數(shù)的memoized(記憶的)值。在依賴不變的情況下,多次定義的時候,返回的值時相同的。
useCallback的性能優(yōu)化:
-
當(dāng)需要將一個函數(shù)傳遞給子組件時,可使用useCallback進(jìn)行優(yōu)化,將優(yōu)化之后的函數(shù),傳遞給子組件
import React, { memo, useCallback, useState } from "react"; const HYIncrement = memo(function (props) { const { increment } = props; console.log("HYIncrement被渲染"); return ( <div> <button onClick={increment}>increment + 1</button> </div> ); }); export default memo(function App() { const [count, setCount] = useState(0); const [message, setMessage] = useState("hello"); // 使用useCallback const increment = useCallback( function () { setCount(count + 1); }, [count] ); // 普通函數(shù) // const increment = () => { // setCount(count + 1); // }; return ( <div> <h2>計數(shù):{count}</h2> <button onClick={increment}>+1</button> <HYIncrement increment={increment} /> <h2>message:{message}</h2> <button onClick={(e) => setMessage("world")}>修改 message</button> </div> ); });
-
進(jìn)一步優(yōu)化文章來源:http://www.zghlxwxcb.cn/news/detail-622976.html
當(dāng)count發(fā)生改變時,也使用同一個函數(shù)文章來源地址http://www.zghlxwxcb.cn/news/detail-622976.html
// 做法一:將count依賴移除掉,缺點:存在閉包陷阱,不依賴count后setCount每次拿到的count并非最新的count // const increment = useCallback(function foo() { // console.log("increment"); // setCount(count + 1); // }, []); // 做法二:利用useRef,在組件多次渲染時,返回同一個值 const countRef = useRef(); countRef.current = count; const increment = useCallback( function foo() { console.log("increment"); setCount(countRef.current + 1); }, [] );
到了這里,關(guān)于【前端知識】React 基礎(chǔ)鞏固(四十四)——其他Hooks(useContext、useReducer、useCallback)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!