React-pdf: React Context not handled correctly (react-redux and react-intl)

Created on 11 Mar 2019  路  5Comments  路  Source: diegomura/react-pdf

Describe the bug
I am using react-redux and react-intl, which both use a provider component and react's context.

When I use a component, in this case on that is connected to the redux store, I get the following error:

Invariant Could not find "store" in the context of "Connect(Compoment)". Either wrap the root component in a , or pass a custom React context provider to and the corresponding React context consumer to Connect(Compoment) in connect options.

Found an issue with react-router, which could be important here:

If you use React Router, something like {() => routes} won鈥檛 work. Due to the way context works in React 0.13, it鈥檚 important that the children are created inside that function. Just referencing an outside variable doesn鈥檛 do the trick. Instead of {() => routes}, write {createRoutes} where createRoutes() is a function that actually creates (and returns) the route configuration.

To Reproduce
Steps to reproduce the behavior including code snippet (if applies):

  1. use a component that uses react's context within react-pdf components
  2. exception is thrown

(I have no time to create a minimal code snippet now, but could do so if someone needs it)

Expected behavior
react-pdf should be able to render components, that rely on reacts context api

Desktop (please complete the following information):

  • OS: linux, Gentoo Linux
  • Browser: chrome and firefox
  • React-pdf/renderer version: v1.4.0

Most helpful comment

https://github.com/ribx/react-pdf-test

import React, {Component} from 'react'
import {createStore} from 'redux'
import ReactDOM from 'react-dom'
import {IntlProvider, FormattedMessage} from 'react-intl'
import {Provider as ReduxProvider, connect} from 'react-redux'
import {Document, Page, View, Text, PDFViewer} from '@react-pdf/renderer'


const store = createStore(state => state)

const Connected = connect(state => ({state}))(props => console.log('state', props.state) || props.children)

class App extends Component {
  render() {
    return (
      <div className="App">
        <PDFViewer>
          <Document>
            <Page>
              <View>
                <Text>
                  <FormattedMessage id="test">{s => s}</FormattedMessage>
                </Text>
              </View>
              <View>
                <Text>
                  <Connected>
                    Redux connected component Test
                  </Connected>
                </Text>
              </View>
            </Page>
          </Document>
        </PDFViewer>
      </div>
    )
  }
}

ReactDOM.render(
  <ReduxProvider store={store}>
    <IntlProvider locale="en" messages={{en: {id: "test", defaultMessage: "React PDF Test"}}}>
      <App/>
    </IntlProvider>
  </ReduxProvider>,
  document.getElementById('root'),
)

I think this is somehow connected to how the new context is working, but I have still problems understanding the concept of react-reconciler.

All 5 comments

A code snippet to replicate this would be great

https://github.com/ribx/react-pdf-test

import React, {Component} from 'react'
import {createStore} from 'redux'
import ReactDOM from 'react-dom'
import {IntlProvider, FormattedMessage} from 'react-intl'
import {Provider as ReduxProvider, connect} from 'react-redux'
import {Document, Page, View, Text, PDFViewer} from '@react-pdf/renderer'


const store = createStore(state => state)

const Connected = connect(state => ({state}))(props => console.log('state', props.state) || props.children)

class App extends Component {
  render() {
    return (
      <div className="App">
        <PDFViewer>
          <Document>
            <Page>
              <View>
                <Text>
                  <FormattedMessage id="test">{s => s}</FormattedMessage>
                </Text>
              </View>
              <View>
                <Text>
                  <Connected>
                    Redux connected component Test
                  </Connected>
                </Text>
              </View>
            </Page>
          </Document>
        </PDFViewer>
      </div>
    )
  }
}

ReactDOM.render(
  <ReduxProvider store={store}>
    <IntlProvider locale="en" messages={{en: {id: "test", defaultMessage: "React PDF Test"}}}>
      <App/>
    </IntlProvider>
  </ReduxProvider>,
  document.getElementById('root'),
)

I think this is somehow connected to how the new context is working, but I have still problems understanding the concept of react-reconciler.

Hi @diegomura, any idea how we can solve this problem. Using context API is a common case.

Hi, just want to mention that I'm having also problems connecting this component to some context, either the Redux one, as well as other used in my current project.

Is there something we can do in order to help you?

cc @diegomura

same issue here, can't inject react intl ... an alternative solution is to connect the parent component and pass data into props but still alternative.

Was this page helpful?
0 / 5 - 0 ratings