skip to Main Content

I am passing data from one page to another in gatsby. First page code:

let state = {book: book, src: src}
return (
<div className="book__holder">
    <Link to="/pdf/" state={state}>
    <Card
        hoverable
        style={{ width: 240 }}
        cover={<img alt={book} 
                    src={url}
                    />}
        >
        <Meta
            title={book}
            description={faculty+" "+year+"-"+part}
        />
    </Card> 
    </Link> 
</div>

This data is used in pdf page as:

const PDFPage = props =>{
    return (
      <React.Fragment>
       <SEO title={props.location.state.book} />
       <NavBar></NavBar>
       <Embed src={props.location.state.src} type="application/pdf">
       </Embed>

     </React.Fragment>
    )}

export default PDFPage

Everything is fine when using gatsby develop but when i use gatsby build it throws following error:

error Building static HTML for pages failed

See our docs page on debugging HTML builds for help https://gatsby.app    
/debug-html

  11 |   return (
  12 |   <React.Fragment>
> 13 |     <SEO title={props.location.state.book} keywords={[`gatsby`,  
           `application`, `react`]} />
     |                                      ^
  14 |     <NavBar></NavBar>
  15 |     <Embed src={props.location.state.src} type="application/pdf">    
           </Embed>
  16 | 


       WebpackError: TypeError: Cannot read property 'book' of undefined

        - pdf.js:13 PDFPage
         lib/src/pages/pdf.js:13:38

Can anyone help me please?

2

Answers


  1. Sometimes you’ll want to pass data from the source page to the linked page. You can do this by passing a state prop to the Link component… The linked page will have a location prop containing a nested state object structure containing the passed data.

    Passing Props to Link targets

    While the following demo is not actually using gatsby, it is using reach router (and gatsby uses reach router under the hood).

    import React from "react";
    import { render } from "react-dom";
    import { Router, Link } from "@reach/router";
    
    const App = () => {
      let state = {
        name: 'Ron',
        book: {
          title: 'Harry Potter and the Deathly Hallows', 
          author: 'J. K. Rowling', 
          progress: '80%'
        }
      }
    
      return (
      <div>
        <h1>App</h1>
        <nav>
          <Link to="/" state={state}>Home</Link>{" "}
          <Link to="dashboard" state={state} >Dashboard</Link>
        </nav>
    
        <Router>
          <Home path="/" />
          <Dashboard path="/dashboard" />
        </Router>
      </div>
    )};
    
    const Home = ({location}) => (
      <div>
        <h2>Welcome { location.state.name }</h2>
        <p></p>
      </div>
    );
    
    const Dashboard = ({location}) => (
      <div>
        <h2>Dashboard</h2>
        <p>Hi { location.state.name }.</p>
        <p>You have read { location.state.book.progress } of { location.state.book.title } by { location.state.book.author }.</p>
      </div>
    );
    
    render(<App />, document.getElementById("root"));
    

    Stackblitz

    Login or Signup to reply.
  2. Gatsby will throw error during production build, since location is not available during server-side rendering.

    One way to make sure the build doesn’t throw an error is to:

    1. Check for the window in componentDidMount
    2. Map the location prop to state
    3. Render the value from your state instead of directly from props

    In componentDidMount()

    componentDidMount() {
      if (typeof window === 'undefined') {
        return;
      }
      this.setState(() => ({ playerName: this.props.location.state.playerName }));
    }
    

    In render()

    render() {
      return <div>{this.state.playerName}</div>;
    }
    

    credit to this thread, How to get previous url in react gatsby

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search