gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.28k stars 10.31k forks source link

Routing #13130

Closed aprather51 closed 5 years ago

aprather51 commented 5 years ago

My Achievement

Rendering page/components inside Sidebar or Mainscreen -- Picture says it all... reach-router-example

Here's what I did...

Used normal react (not gatsby ) and reach-router to achieve this. react-router will work same.

import React from "react";
import styled from "styled-components";
import { Router, Link } from "@reach/router";

const App = () => {
  return (
    <Main>
      <Sidebar>
        <nav>
          <Link to="/"> Home</Link>
          <Link to="/dashboard"> Dashboard</Link>
          <Link to="/third"> Third</Link>
        </nav>
        <Router>
          <Home path="/" />
          <Dashboard path="dashboard" />
        </Router>
      </Sidebar>
      <Mainscreen>
        <Router>
          <Third path="third" />
        </Router>
      </Mainscreen>
    </Main>
  );
};

export default App;

/* Home */
const Home = () => (
  <h1>Home Page</h1>
)

/* Dashboard */
const Dashboard = () => (
  <h1>Dashboard Page</h1>
)

/* Third */
const Third = () => (
  <h1>Third Page</h1>
)

/* Styled */
const Main = styled.div`
    display: grid;
    grid-template-columns: 32vw auto;
`;

const Mainscreen = styled.div`
    background-color: #fff;
    height: 100vh;
`;

const Sidebar = styled.div`
    background-color: #eee;
    height: 100vh;
`;

The Goal

To establish same way as above inside Gatsby...

import React from 'react';
import { Link } from 'gatsby';
import styled from 'styled-components';
import Layout from '../components/layout';

const IndexPage = () => (
    <Layout>
        <Main>
            <Sidebar>
                <h1>Sidebar</h1>
                <nav>
                    <Link to="/">Home</Link> 
                                        <br />
                    <Link to="/page-2">Page2</Link>
                                        <br />
                    <Link to="/page-3">Page3</Link>
                </nav>
            </Sidebar>
            <Mainscreen>
                <h1>MainScreen</h1>
            </Mainscreen>
        </Main>
    </Layout>
);

export default IndexPage;

/* Styled */
const Main = styled.div`
    display: grid;
    grid-template-columns: 32vw auto;
`;

const Mainscreen = styled.div`
    background-color: #fff;
    height: 100vh;
`;

const Sidebar = styled.div`
    background-color: #eee;
    height: 100vh;
`;

The result... gatsby-route-result

Apparently, it does not meet my exception! It does not render components/page inside Sidebar or Mainscreen but went direct into new page instead. Due to lack of information on Gatsby-Link, I believe,if not mistaken since v2, Gatsby-Link uses reach-router to achieve the result. So, by playing guessing game I have included Router as second importer and set <Router> with path exactly same way I did above...

...
import { Router, Link } from 'gatsby';

import Home from './index';
import Page2 from './page-2';
...
<Layout>
    <Sidebar>
        <h1>Sidebar</h1>
            <nav>
             <Link to="/">Home</Link> 
                         <br />
             <Link to="/page-2">Page2</Link>
                         <br />
             <Link to="/page-3">Page3</Link>
                          <Router>
                    <Home path="/" />
                <Page2 path="page-2" />
            </Router>
             </nav>
    </Sidebar>
    <Mainscreen>
        <h1>MainScreen</h1>
    </Mainscreen>
        </Main>
</Layout>

Unfortunately, It didn't work 😏. My another guessing game, I have Installed @reach-router dependable and replace it from Gatsby-Link.

//import { Router, Link } from 'gatsby';
import { Router, Link } from '@reach/router';
...

Another failed guessing game... I have hit wall, got stuck. Need some help... what's better way?

Thanks in advance...

pieh commented 5 years ago

Can you provide entire repo - it's hard to see complete picture of your setup from those snippet

aprather51 commented 5 years ago

Hope CodeSandbox.io is okay...

React & @reach/router ( preview example) - my objective result. https://codesandbox.io/embed/nkymxpy0m0?fontsize=14

The issues I am having with Gatsby.... https://codesandbox.io/embed/github/aprather51/-issues-gatsby-routing/tree/master/

Environment

  System:
    OS: Windows 10
    CPU: (8) x64 AMD FX(tm)-8320 Eight-Core Processor
  Binaries:
    Node: 10.12.0 - /tmp/yarn--1554423877294-0.9393323839850403/node
    Yarn: 1.15.2 - /tmp/yarn--1554423877294-0.9393323839850403/yarn
    npm: 6.8.0 - /usr/bin/npm
  Languages:
    Python: 2.7.12 - /usr/bin/python
  npmPackages:
    gatsby: ^2.3.5 => 2.3.5
    gatsby-image: ^2.0.37 => 2.0.37
    gatsby-plugin-manifest: ^2.0.26 => 2.0.26
    gatsby-plugin-offline: ^2.0.25 => 2.0.25
    gatsby-plugin-react-helmet: ^3.0.11 => 3.0.11
    gatsby-plugin-sharp: ^2.0.32 => 2.0.32
    gatsby-source-filesystem: ^2.0.28 => 2.0.28
    gatsby-transformer-sharp: ^2.1.17 => 2.1.17

Done in 5.61s.
jonniebigodes commented 5 years ago

@aprather51 i think i have a solution for you. If you don't mind the wait, i'll post it tomorrow when i get home, just need to run a couple of more tests and, as it's 2:12 am where i'm at so...i need some sleep! Sounds good?

aprather51 commented 5 years ago

Sure 👍... I don't mind the wait.

jonniebigodes commented 5 years ago

@aprather51 like i said earlier, if i read and understood what you need to implement, below are the steps i took to solve your issue.

export default () => (

Dashboard Page

this is a dashboard

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Quisque egestas diam in arcu cursus. Viverra suspendisse potenti nullam ac tortor vitae purus faucibus. Gravida cum sociis natoque penatibus et. Ullamcorper a lacus vestibulum sed arcu non odio euismod lacinia. Egestas pretium aenean pharetra magna. Amet aliquam id diam maecenas. Eget magna fermentum iaculis eu non diam phasellus vestibulum. Dictum non consectetur a erat nam at lectus urna. Mauris vitae ultricies leo integer malesuada nunc vel risus commodo. In arcu cursus euismod quis viverra nibh. Elementum nibh tellus molestie nunc non blandit massa enim nec. Euismod lacinia at quis risus sed vulputate odio ut enim. Molestie ac feugiat sed lectus vestibulum mattis ullamcorper. Scelerisque felis imperdiet proin fermentum leo vel orci porta. Nec feugiat in fermentum posuere urna nec tincidunt praesent. Massa tempor nec feugiat nisl pretium fusce id velit ut. Mi in nulla posuere sollicitudin aliquam. Ipsum nunc aliquet bibendum enim facilisis gravida neque convallis a. Enim diam vulputate ut pharetra sit amet aliquam id. Urna condimentum mattis pellentesque id nibh tortor. Gravida rutrum quisque non tellus orci ac auctor augue. Sed turpis tincidunt id aliquet risus. Ornare massa eget egestas purus. Ornare aenean euismod elementum nisi quis. Leo vel orci porta non pulvinar neque laoreet. Purus gravida quis blandit turpis cursus in hac.

)

- `side-home.js` has the following content:
```javascript
import React from "react"

export default () => (
  <div>
    <h1>This is the sidebar home</h1>
  </div>
)

export default () => (

Third Page

    {[0, 1, 2, 3, 4, 5].map(item => (
  • {item}
  • ))}

)


- `pages/index.js` has the following content, left some comments in there,so that when you read this you'll get a sense of what is happening:
```javascript
import React from "react"
import Third from "../components/third"
import Dashboard from "../components/dashboard"
import SideHome from "../components/side-home"

import { Router, Link, Location } from "@reach/router"

const Index = () => (
  <div
    style={{
      display: "flex",
      justifyContent: "center",
      maxWidth: "960px",
      marginRight: "20px",
    }}
  >
    <div style={{ border: "4px solid lightblue" }}>
      <h1>Sidebar</h1>
      {/* navbar with links, react-router ones, not gatsby ones despite being internal ones */}
      <nav>
        <Link to="/" style={{ margin: "0.85rem" }}>
          Home
        </Link>
        <Link to="/two" style={{ margin: "0.85rem" }}>
          second
        </Link>
        <Link to="/three" style={{ margin: "0.85rem" }}>
          three
        </Link>
      </nav>
      {/* adds the router specific to this page only */}
      <SideBarRouter>
        <Page path="/">home</Page>
        <Page path="/two">page2</Page>
        <Page path="/three">Third</Page>
      </SideBarRouter>
    </div>
    <div style={{ border: "4px solid rebeccapurple", margin: "2px" }}>
      <h1>main screen</h1>
      <div>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Mollis
          nunc sed id semper risus in hendrerit gravida rutrum. Placerat duis
          ultricies lacus sed turpis. Lobortis elementum nibh tellus molestie
          nunc. Nunc mattis enim ut tellus elementum. Scelerisque in dictum non
          consectetur a erat nam at. Faucibus et molestie ac feugiat sed lectus.
          Nunc mattis enim ut tellus elementum sagittis vitae et. Amet mauris
          commodo quis imperdiet massa tincidunt nunc. Nunc pulvinar sapien et
          ligula ullamcorper. Aliquet risus feugiat in ante metus dictum at
          tempor. Ut sem viverra aliquet eget sit amet tellus cras. Ultricies
          lacus sed turpis tincidunt id aliquet risus feugiat in.
        </p>
        <p>
          Non enim praesent elementum facilisis leo vel. Integer quis auctor
          elit sed vulputate mi. Odio facilisis mauris sit amet massa vitae
          tortor condimentum. Lorem ipsum dolor sit amet consectetur adipiscing
          elit. Sed turpis tincidunt id aliquet. Ac tortor vitae purus faucibus
          ornare. Mattis aliquam faucibus purus in massa tempor nec. Erat
          pellentesque adipiscing commodo elit at imperdiet dui. Nunc id cursus
          metus aliquam. Nulla at volutpat diam ut venenatis. Tortor pretium
          viverra suspendisse potenti nullam ac tortor vitae purus. Euismod
          lacinia at quis risus.
        </p>
        <p>Oh. You need a little dummy text for your mockup? How quaint.</p>
        <p>I bet you’re still using Bootstrap too…</p>
      </div>
    </div>
  </div>
)
// functional component that will render the "pages" inside the components folder 
// all based on the path recieved as props 
const Page = props => {
  const { path } = props
  if (path === "/two") {
    return (
      <div
        className="page"
        style={{ background: `hsl(${props.page * 75}, 60%, 60%)` }}
      >
        <h4>this is a nested page</h4>
        <hr />
        <Dashboard />
      </div>
    )
  }
  if (path === "/three") {
    return (
      <div
        className="page"
        style={{ background: `hsl(${props.page * 75}, 60%, 60%)` }}
      >
        <h4>this is a nested page</h4>
        <hr />
        <Third />
      </div>
    )
  }
  return (
    <div
      className="page"
      style={{ background: `hsl(${props.page * 75}, 60%, 60%)` }}
    >
      <h4>this is a nested page</h4>
      <hr />
      <SideHome />
    </div>
  )
}
// hoc functional component that will inject a context, this case the context that @react-router offers
// will render the page component based on the route recieved as props 
const SideBarRouter = props => (
  <Location>
    {({ location }) => (
      <div>
        <Router location={location}>{props.children}</Router>
      </div>
    )}
  </Location>
)

export default Index

test_aprather51_client_page_1

test_aprather51_client_page_2

test_aprather51_client_page_3

test_aprather51_second_page

To sum it up, what this reproduction is doing and what i take from what you described in this issue, is nothing more nothing less than applying the same strategy used in the client-only-paths example, with some twists. For one, i'm not using transitions of any sorts, two, the pages/index.js in this line is returning {props.page} and it will not work as that said property will return undefined. Checking devtools and there's no reference of the said property. Probably it was removed with a version update. Also before i forget, when you navigate to another page, like for instance in my case, for page-2 and go back, the page shown inside the sidebar will be the last one viewed.

Feel free to provide feedback, so that we can close this issue or continue to work on it until a solution is found.

aprather51 commented 5 years ago

@jonniebigodes - Your reproduction are pretty much closer to what I am looking for. The "Third" component should have page flip on Mainscreen instead of sidebar however, its not important. After going on many reproductions and testing, following from your example. I found missing onCreatePage inside gatsby-node.js is the problem! It solve everything after reading docs. Thank you @johnniebigodes for you help.

reach-router-example

jonniebigodes commented 5 years ago

@aprather51 no need to thank. Glad that i was able to help you solve your issue 👍