useContext Hook 是如何工作的

所有這些新的 React Hook之間都有一個宗旨:就是為了使函數組件像類組件一樣強大。

useContext hook 與其它幾個有點不一樣,但它在特定場景下還是很有用的。

React 的 Context API 是一種在應用程序中深入傳遞數據的方法,而無需手動一個一個在多個父子孫之間傳遞 prop。當咱們需要的只是傳遞數據時,它可以作為像Redux這樣的工具的一個很好的替代。

useContext Hook 是如何工作的

使用 Context ,首先頂層先聲明 Provier 組件,並聲明 value 屬性,接著在後代組件中聲明 Consumer 組件,這個 Consumer 子組件,只能是唯一的一個函數,函數參數即是 Context 的負載。如果有多個 Context ,Provider 和 Consumer 任意的順序嵌套即可。

此外我們還可以針對任意一個 Context 使用 contextType 來簡化對這個 Context 負載的獲取。但在一個組件中,即使消費多個 Context,contextType 也只能指向其中一個。

useContext Hook 是如何工作的

在 Hooks 環境中,依舊可以使用 Consumer,但是 ContextType 作為類靜態成員肯定是用不了。Hooks 提供了 useContext,不但解決了 Consumer 難用的問題同時也解決了 contextType 只能使用一個 context 的問題。

標準方式

使用 API的典型方法如下所示:

import React from "react";
import ReactDOM from "react-dom";
// 創建 Context
const NumberContext = React.createContext();
// 它返回一個具有兩個值的對象
// { Provider, Consumer }
function App() {
// 使用 Provider 為所有子孫代提供 value 值
return (
<numbercontext.provider>

<display>

/<numbercontext.provider>
);
}
function Display() {
// 使用 Consumer 從上下文中獲取 value
return (
<numbercontext.consumer>
{value =>
The answer is {value}.
}
/<numbercontext.consumer>
);
}
ReactDOM.render(, document.querySelector("#root"));

可以 CodeSandbox上看看運行效果。

使用 useContext 方式

使用 useContext hook 來重寫上面的示例

import React, { useContext } from 'react';
// ...
function Display() {
const value = useContext(NumberContext);
return
The answer is {value}.
;
}

調用useContext,傳入從React.createContext獲取的上下文對象。

唯一需要注意的是你必須將整個上下文對象傳遞給useContext - 而不僅僅是Consumer, 當然如果忘記了,React會給出警告。

嵌套的 Consumers

你可能遇到這樣的情況,咱們的組件需要從多個父級上下文中接收數據,從而導致這樣的代碼

function HeaderBar() {
return (
<currentuser.consumer>
{user =>
<notifications.consumer>
{notifications =>

<header>
Welcome back, {user.name}!
You have {notifications.length} notifications.
/<header>
}
}
/<notifications.consumer>/<currentuser.consumer>
);
}

這種大量嵌套只是為了接收兩個值。下面是使用useContext時的效果:

function HeaderBar() {
const user = useContext(CurrentUser);
const notifications = useContext(Notifications);
return (
<header>
Welcome back, {user.name}!
You have {notifications.length} notifications.
/<header>
);
}

​總結

useContext 接收一個 context 對象(React.createContext 的返回值)並返回該 context 的當前值。當前的 context 值由上層組件中距離當前組件最近的 <countcontext.provider> 的 value prop 決定。/<countcontext.provider>

當組件上層最近的 <countcontext.provider> 更新時,該 Hook 會觸發重渲染,並使用最新傳遞給 CountContext provider 的 context value 值。/<countcontext.provider>

別忘記 useContext 的參數必須是 context 對象本身:

  • 正確:useContext(MyContext)
  • 錯誤:useContext(MyContext.Consumer)
  • 錯誤:useContext(MyContext.Provider)

調用了 useContext 的組件總會在 context 值變化時重新渲染。如果重渲染組件的開銷較大,你可以 通過使用 memoization 來優化。

代碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。

參考:

https://daveceddia.com/usecontext-hook/

交流

關注公眾號,後臺回覆福利,即可看到福利,你懂的。


useContext Hook 是如何工作的


分享到:


相關文章: