linking libraries: react-redux

2021-05-20

 | 

~3 min read

 | 

426 words

I’ve written in the past about linking a library to an application where both use React and the problems that can ensue - specifically an apparent violation of the Rule of Hooks.

The solution in that case was linking the application’s version of react, using it in the library and then linking the library for use in the application.

It turns out this exact same pattern is needed to solve a potential problem when you want to use react-redux.

It’s worth being explicit: this issue only applies and the following solution is only relevant when testing locally and trying to link a library to an application where both have dependencies on react-redux.

Digging In: Error: could not find react-redux context value

In the case of react-redux the error thrown is not an invalid hook call, but missing context:

Error: Uncaught [Error: could not find react-redux context value; please ensure the component is wrapped in a <Provider>]

I scratched my head for a long time on this because the app was definitely wrapped in a <Provider>. A stylized example of what my application looked like:

app/index.ts
import * as React from "react"
import * as ReactDOM from "react-dom"
import { createStore } from "react-redux"
import { LibraryComponents } from "@scoped/internal-package"

const App = () => {
  const store = createStore(reducer)

  return (
    <Provider store={store}>
      <LibraryComponents />
    </Provider>
  )
}

ReactDOM.render(<App />, this.element)
library/src/LibraryComponent.ts
import * as React from "react"
import { useSelector } from "react-redux"

export function LibraryComponent() {
  const state = useSelector((x) => x)
  return (
    <pre>
      <code>{JSON.stringify(state, null, 4)}</code>
    </pre>
  )
}

It was only after several hours of bouncing around that I remembered I had previously solved a similar issue with react! (It’s lovely to have solved a problem before. Even better to have written it down. But it’s all for naught if you don’t remember!)

Solving The Issue

As with react, the solution is an annoyingly complicated dance of linking the correct packages:

% pwd
~/code/my-app
% cd ./node_modules/react-redux
% yarn link
yarn link v1.22.4
success Registered "react-redux".
info You can now run `yarn link "react-redux"` in the projects where you want to use this package and it will be used instead.
✨  Done in 0.06s.

Then, moving over to the library,

% cd ~/code/my-lib
yarn link "react-redux"

Now that the library is using the application’s react-redux, I can link the library and test the interaction to my heart’s delight without needing to publish a new version.


Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!