Cannot call state from redux in react-pdf component

70 Views Asked by At

i am trying to firgure out how to use this react-pdf lib in my project. At first I tried to render the state directly from redux store into a react-pdf component and it didn't worked.

It shows the Error:

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

I have many other components which have used the state from redux and none of them have this problem until I tried to render a component from react-pdf within and .

Here is a part of my code:

const ConfigurationListPdf = (props)=> {
    const mech = useSelector(mechConfig);
    return(
            <>
                <Document>
                    <Page size="A4" style={styles.page}>
                        <View style={styles.section}>
                            <Text>
                                {props.elem}
                            </Text>
                        </View>
                    </Page>
                </Document>
            </>
        )
}

export default function InfoBoard(){
    const styles = StyleSheet.create({
        page: {
            flexDirection: 'row',
        },
        section: {
            margin: 10,
            padding: 10,
            flexGrow: 1
        }
    });

// Create Document Component
    return(
        <>
            <CntrInfoBoard>
                <InnerBoard>
                    <TitelDiv>
                    <Typography variant="h5" sx{{color:'white',fontWeight:900}}>Summary</Typography>
                    </TitelDiv>
                    <CntrInfoDetails>
                        <NodeTable/>
                    </CntrInfoDetails>
                    <Terms>
                        <p>
                            xxx
                        </p>
                    </Terms>
                    <PDFViewer>
                        <ConfigurationListPdf />
                    </PDFViewer>
                    <CntrSaveBtn>
                        <BtnSave>Configuration save</BtnSave>
                        <BtnOther>Sign up to finish</BtnOther>
                        <BtnOther onClick={savePdfHandler}>
                            {/*Save to PDF*/}
                            <PDFDownloadLinkStyled
                                document={<ConfigurationListPdf/>}
                                fileName="example.pdf"
                            >
                                Download PDF
                            </PDFDownloadLinkStyled>
                        </BtnOther>
                    </CntrSaveBtn>
                </InnerBoard>
            </CntrInfoBoard>
        </>
    )
}

Sorry if there is a problem with the code formatting.

As long as I add a useSelector or useDispatch it shows the error.

This is weird because the has already been wrapped in my index.js:

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <Provider store={store}>
            <App/>
        </Provider>
    </React.StrictMode>
);

I thought my redux store has a problem so I tried to call state and reducers in other components without react-pdf and turns out that's not the case. They work fine.

Any idea?

1

There are 1 best solutions below

1
Drew Reese On

I've run into similar issues when trying to render PDF content. I believe the issue is that the PDFViewer and PDFDownloadLink components render iframe elements and so the React components under them are likely rendered into separate sub-ReactTrees from your app context that has the Redux provider.

To get around this access the Redux state from higher in the ReactTree than either of PDFViewer and PDFDownloadLink, e.g. in the InfoBoard component, and pass down the selected state as props to the ConfigurationListPdf component.

Example:

const ConfigurationListPdf = ({ elem, mech })=> {
  // use mech prop now

  return (
    <Document>
      <Page size="A4" style={styles.page}>
        <View style={styles.section}>
          <Text>
            {elem}
          </Text>
        </View>
      </Page>
    </Document>
  );
}
export default function InfoBoard() {
  const mech = useSelector(mechConfig); // <-- select from Redux in parent

  // Create Document Component
  return (
    <>
      <CntrInfoBoard>
        <InnerBoard>
          ....
          <PDFViewer>
            <ConfigurationListPdf mech={mech} /> // <-- pass mech as prop
          </PDFViewer>
          <CntrSaveBtn>
            <BtnSave>Configuration save</BtnSave>
            <BtnOther>Sign up to finish</BtnOther>
            <BtnOther onClick={savePdfHandler}>
              {/*Save to PDF*/}
              <PDFDownloadLinkStyled
                document={(
                  <ConfigurationListPdf
                    mech={mech} // <-- pass mech as prop
                  />
                )}
                fileName="example.pdf"
              >
                Download PDF
              </PDFDownloadLinkStyled>
            </BtnOther>
          </CntrSaveBtn>
        </InnerBoard>
      </CntrInfoBoard>
    </>
  );
}

const styles = StyleSheet.create({
  page: {
    flexDirection: 'row',
  },
  section: {
    margin: 10,
    padding: 10,
    flexGrow: 1
  }
});