踩坑:在多个包之间使用同一个React Context

记录一下最近写个人页遇到的一个问题。

0x00 问题背景

假设有这样一个组件库my-compnents和这样一个页面工程my-project,它们同时依赖some-depsome-dep导出了一个ContextTheme用于给整个页面提供主题。my-components导出了一个内部使用Theme的组件Componentmy-project中的一个页面结构如下:

import { MyComponent } from 'my-components';
import { Theme, createTheme } from 'some-dep'

function index() {
  const myTheme = createTheme();

  return (
    <Theme.Provider theme={myTheme}>
      { /* 来自my-components的组件MyComponent内部导入了来自some-dep的Theme.Consumer */ }
      <MyComponent />
    <Theme.Provider>
  )
}

看起来似乎没有什么问题。但是,在MyComponent内部取Context的话,只会得到undefined

0x01 问题成因

很容易就能想到,问题可能出在打包这个过程中。在这个例子中,我们在my-projectmy-components中分别地导入了some-dep。相互独立的导入过程产生了两个相互独立的Context。

我们在my-project中使用createTheme实例化了Context对象并传给my-project中的Provider,但这一切与my-components无关。my-components有独立的Context,但是这个Context始终没有被createTheme实例化(毕竟,设计本意只是想让组件去拿整个上下文中的Context对象),MyComponent中的Consumer也就只能获取到undefined了。

0x02 解决方案

我们需要让两个包使用同一个Context,准确来说,是my-project定义的那个。具体的方法是,在使用Consumer的地方(也就是my-component)将提供Provider的包(也就是some-dep)定义为external

// webpack
{
   ...
   externals: {
      ...
      'some-dep': 'some-dep'
   },
   ...
}

// rollup
{
  ...
  external: ['some-dep'],
  ...
}

这样,问题就解决了。


参考链接:

  1. javascript - React Context API not working from custom NPM component library - Stack Overflow

本文链接:

https://www.direcore.xyz/archives/38/
1 + 8 =
快来做第一个评论的人吧~