useContext Hook 是如何工做的

想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!html


阿里云最近在作活动,低至2折,有兴趣能够看看promotion.aliyun.com/ntms/yunpar…前端


为了保证的可读性,本文采用意译而非直译。react

全部这些新的React Hook之间都有一个宗旨:就是为了使函数组件像类组件同样强大。git

useContext hook 与其它几个有点不同,但它在特定场景下仍是颇有用的。github

React 的 Context API 是一种在应用程序中深刻传递数据的方法,而无需手动一个一个在多个父子孙之间传递 prop。当我们须要的只是传递数据时,它能够做为像Redux这样的工具的一个很好的替代。数组

使用 Context ,首先顶层先声明 Provier 组件,并声明 value 属性,接着在后代组件中声明 Consumer 组件,这个 Consumer 子组件,只能是惟一的一个函数,函数参数便是 Context 的负载。若是有多个 Context ,ProviderConsumer 任意的顺序嵌套便可。dom

此外咱们还能够针对任意一个 Context 使用 contextType 来简化对这个 Context 负载的获取。但在一个组件中,即便消费多个 Context,contextType 也只能指向其中一个。ide

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 value={42}>
      <div>
        <Display />
      </div>
    </NumberContext.Provider>
  );
}

function Display() {
  // 使用 Consumer 从上下文中获取 value
  return (
    <NumberContext.Consumer>
      {value => <div>The answer is {value}.</div>}
    </NumberContext.Consumer>
  );
}

ReactDOM.render(<App />, document.querySelector("#root"));
复制代码

能够 CodeSandbox上看看运行效果。

使用 useContext 方式

使用 useContext hook 来重写上面的示例

import React, { useContext } from 'react';

// ...

function Display() {
  const value = useContext(NumberContext);
  return <div>The answer is {value}.</div>;
}
复制代码

调用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>
          }
      }
    </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> 更新时,该 Hook 会触发重渲染,并使用最新传递给 CountContext provider 的 context value 值。

别忘记 useContext 的参数必须是 context 对象自己:

  • 正确: useContext(MyContext)
  • 错误: useContext(MyContext.Consumer)
  • 错误: useContext(MyContext.Provider)

调用了 useContext 的组件总会在 context 值变化时从新渲染。若是重渲染组件的开销较大,你能够 经过使用 memoization 来优化。

代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug

参考:

daveceddia.com/usecontext-…

交流(欢迎加入群,群工做日都会发红包,互动讨论技术)

阿里云最近在作活动,低至2折,有兴趣能够看看:promotion.aliyun.com/ntms/yunpar…

干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。

github.com/qq449245884…

我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,便可看到福利,你懂的。

相关文章
相关标签/搜索