欢迎光临散文网 会员登陆 & 注册

React手册 Hooks 之 useContext

2023-05-11 16:09 作者:海里我最大  | 我要投稿

描述

    React 官网对 useContext 的描述原文

    useContext is a React Hook that lets you read and subscribe to context from your component.

    useContext是一个React Hook它可以让你从组件中读取和订阅上下文.

场景

    主要的使用在需要多层嵌套组件之间, 父组件向子组件传递数据的场景, 如果是单层嵌套组件之间参数传递可以使用 props.

    当需要从 App 组件把值透过 Con 组件传给 Inner 组件时, 如果还是使用 props, 就需要从 Con 组件接收并传递给 Inner 这个步骤其实是多余的, 而且会让 Con 组件变得更复杂, 使用 useContext 之后, 就可以跳过 Con 组件, 直接在 Inner 组件中获取到对应的值, 并且每次 theme 变化之后, 都会重新渲染 Inner, 将最新的结果展示.


参数

  • context: ReactContext

    使用 React.createContext 方法创建出来的 Context 对象, 它本身并不包含任何数据, 只是一个可供传递和从组件中读取数据的对象类型.

返回

  • Any

    useContext 返回组件调用的 context 对应的 value, 也就是 <Context.Provider> 标签上 value 属性对应的值, 如果没有这个提供者(Provider), 那么就是你在使用 React.createContext 时传入的初始值, 当 context 对应的值发生变化, React 会更新那些使用了该 context 的组件.

用法1

    深层嵌套时, 父级节点向子集节点传递数据, 这个关系不能反过来, 也就是说, 使用 useContext 的节点, 只会从所有父级节点中, 找到距离自己最近的一个 <Context.Provider> 标签, 并返回标签中指定的 value.

    父级组件 MyPage:

    子级组件 FormButton:


用法2

    更新 Provider 中指定的 value, 通常情况下我们传递的值都需要发生变化, 以满足需求, useContext 可以和 useState 结合在一起使用

    也可以指定对象和函数类型的值, 将 set 函数传递进去, 可以从子组件发起修改, 或将父组件的函数传递给子组件, 实现子组件给父组件传值, 例子中的 myAppFunction 方法, 可以在子级中通过 useContext(CurrentUserContext).myAppFunction 获取并执行.

    在上面的例子中, 每次 MyApp 重新渲染时, CurrentUserContext.Provider 也会重新绑定value, 但是传给 value 的值是一个常量对象 {}, 所以不管 MyApp 的重新渲染是否与 CurrentUserContext.Providervalue 有关, 都会让它检测到变化, 并通知所有订阅了CurrentUserContext 的子组件重新渲染, 在大型组件中, 这造成性能浪费.

    使用下面的方式改写

    这样使用 useCallbackuseMemo 改写之后, 只有当 CurrentUserContext.Provider 的值 contextValue 发生变化时, 才会去更新相关的子组件, 起到优化渲染的效果.


用法3

    多个 Context 混用, 在实际开发的业务场景中, 单一的 Context 往往不能满足需求, 需要多个 Countext 一起使用

    上面例子中, 子组件 UserInfo 可以同时从 ThemeContextCurrentUserContext 两个Context 中获取数据, 但是可能你也发现了一个问题, 那就是当 Context 很多的时候, 需要一直嵌套, 这样让原本单一的节点结构变得很复杂, 可以像下面这个样改写

    这样可以将原本抽象的 <Context.Provider> 抽离出去, 让 MyApp 组件更加容易理解.

    多个 Context 混用时, 有时会出现同一个 Context 多次嵌套使用的情况, 也就是覆盖的情况

    在这个例子中, Footer 有两个父级 <ThemeContext.Provider> 标签, 在 Footer 中使用 useContext(ThemeContext) 时, 获取的是距离 Footer 最近的 <ThemeContext.Provider> 标签所对应的 value, 也就是 "light", 而距离较远的 "dark" 就被覆盖了.


总结

  • useContext 主要用于多层嵌套组件之间, 父组件向子组件之间传递数据, 同一组件内无法使用 useContext 获取到最新数据.

  • useContext 接收的参数必须是 React.createContext 创建出来的 Context 对象, 返回<Context.Provider> 绑定的值, 如果没有找到则返回 React.createContext 创建时的默认值, 此默认值不可变.

  • <Context.Provider> 绑定的值发生变化时, 会通知所有 useContext(Context) 的子组件重新渲染, 并且渲染会跳过 React.memo.

  • <Context.Provider> 可以传递对象和函数, 但是需要配合 useMemouseCallback 对数据进行合理的缓存, 以免造成不必要的更新.

  • <Context.Provider> 可以嵌套使用, 相同的 Context 嵌套多次, 距离调用 useContext 近的 <Context.Provider> 标签会覆盖距离较远的.


React手册 Hooks 之 useContext的评论 (共 条)

分享到微博请遵守国家法律