Import react components in gatsby JS

Import react components in gatsby JS
0
#1

I am building a Gatsby JS blog.
Below is my planning when it comes to what get rendered into the index page.

How do I import the bio.js into layout.js?

layout.js file:

import React from "react"
import PropTypes from "prop-types"
import { StaticQuery, graphql } from "gatsby"

import Header from "./header"
import Footer from "./footer"
import bio from "../pages/bio"
import "./layout.css"

const Layout = ({ children }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <Header siteTitle={data.site.siteMetadata.title} />
        <div
          style={{
            margin: `0 auto`,
            maxWidth: 960,
            padding: `0px 1.0875rem 1.45rem`,
            paddingTop: 0,
          }}
        >
          <main>{children}</main>
        </div>
        <bio/>
        <Footer />
      </>
    )}
  />
)

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

bio.js file:

import React from "react"
import Layout from "../components/layout"
import SEO from "../components/seo"
import profile_pic from "../images/profile_pic.png"
import 'bootstrap/dist/css/bootstrap.css'

const bio = ({data}) => (
  <Layout>
    <SEO title="slowpacedcoding" keywords={[`slowpacedcoding`, `web development`, `Matt Zhou`]} />

    <h3 style={{
      fontFamily: `'Montserrat', sans-serif`,
      fontWeight: 400,
      marginTop:`1rem`,
      color: `#f47c48`,
    }}>Bio</h3>
    <img src={profile_pic} alt="profile_pic" style={{
      width:`100px`,
    }}></img>
    <p style={{
      fontFamily: `'Montserrat', sans-serif`,
    }}>
    Former student of Singapore Polytechnic, dropped out at the end of year two, had been
    learning Web-Development since 2016. My goal is to become a web developer in an English speaking country.
    </p>

    <h5 style={{
      fontFamily: `'Montserrat', sans-serif`,
    }}>Find me at :</h5>

    <div>
      <a href="https://www.linkedin.com/in/xiang-zhou-03547755/" rel='noopener noreferrer' target="_blank" style={{backgroundColor: `#fff5e8`,color:`black`,textDecoration:`none`,}}>LinkedIn</a>
      <a href="https://github.com/zhouxiang19910319" rel='noopener noreferrer' target="_blank"  style={{backgroundColor: `#fff5e8`,color:`black`,textDecoration:`none`,}}>github</a>
      <a href="https://medium.freecodecamp.org/the-most-difficult-things-about-learning-to-code-by-yourself-b24ac8c3c23a "
      rel='noopener noreferrer' target="_blank" style={{backgroundColor: `#fff5e8`,color:`black`,textDecoration:`none`,}}>medium</a>
      <a href="https://twitter.com/zh0ux1ang" rel='noopener noreferrer' target="_blank" style={{backgroundColor: `#fff5e8`,color:`black`,textDecoration:`none`,}}>twitter</a>
      <a href="https://www.freecodecamp.org/zhouxiang19910319" rel='noopener noreferrer' target="_blank" style={{backgroundColor: `#fff5e8`,color:`black`,textDecoration:`none`,}} >freeCodeCamp</a>
    </div>

  </Layout>
)

export default bio
0 Likes

#2

Perhaps make bio.js a full on class component, and add it to your layout.js component. I wouldn’t think you would need to include your layout component directly in your bio component.

So instead of import bio from '../pages/bio' you could export your bio component and import that into your layout component like import { Bio } from '../components/bio'.

Think of it this way. By looking at your design, it would seem to me bio.js should not be a page on its own but rather a component you can sit adjacent to your post component. You could wrap them in a <React.Fragment>` and have something like you’ve designed here.

1 Like

#3

Every component in React need to use Title Case by convention, so change your bio to Bio and use standard import - export will do

1 Like

#4

It’s not just convention – every React component must start with an uppercase letter. Otherwise react will treat it as an HTML tag.

1 Like

#5

new layout.js

import React from "react"
import PropTypes from "prop-types"
import { StaticQuery, graphql } from "gatsby"

import Header from "./header"
import Footer from "./footer"
import {Bio} from "./bio"
import "./layout.css"

const Layout = ({ children }) => (
  <StaticQuery
    query={graphql`
      query SiteTitleQuery {
        site {
          siteMetadata {
            title
          }
        }
      }
    `}
    render={data => (
      <>
        <Header siteTitle={data.site.siteMetadata.title} />
        <div
          style={{
            margin: `0 auto`,
            maxWidth: 960,
            padding: `0px 1.0875rem 1.45rem`,
            paddingTop: 0,
          }}
        >
          <main>{children}</main>
        <Bio />
        </div>
        <Footer />
      </>
    )}
  />
)

Layout.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Layout

bio.js

import React from "react"
// import Layout from "./layout"
// import SEO from "./seo"
// import profile_pic from "../images/profile_pic.png"
import { Component, Fragment } from 'react'
import { constants } from "os"
// import 'bootstrap/dist/css/bootstrap.css'

class Bio extends React.Component{
  render (){
    return(
        <h1>Hello world</h1>
    )
  }
}

export default Bio

These two will get me this error:

×
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it’s defined in, or you might have mixed up default and named imports.

Check the render method of Context.Consumer.

0 Likes

#6

also in the terminal it says:

"export 'Bio' was not found in './bio'

0 Likes

#7

Why you’re doing named import when you’re not doing named export?

It should be this I believe:
import Bio from "./bio"

1 Like

#8

Thanks for the reply and it solved my problem.

Another question:

with both index.js + layout.js present, where do I put the styling of my main page??
I am using react-bootstrap right now.
Should I put everything in layout.js or??
If I do, what should I put in index.js?

This is my current index.js file:

import React from "react"
import { Link } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"
import 'bootstrap/dist/css/bootstrap.css';
import Container from 'react-bootstrap/Container'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'



const IndexPage = () => (
  <Layout>
    <SEO title="slowpacedcoding" keywords={[`slowpacedcoding`, `programming`, `Matt Zhou`, `gatsbyJS`,`web development`,`zhouxiang19910319`,`web programming`]} />

    <Container>
      <Row>
        <Col xl={6} lg={6} md={12} sm={12} xs={12}>
          {/* BLOG POST SECTION IS HERE! */}
          <Link to="/blog" style={{textDecoration:`none`,display:`inline-block`}}><h3 style={{
          fontFamily: `'Montserrat', sans-serif`,
          fontWeight: 400,
          color: `#f47c48`,
          marginLeft:`-1rem`,
          }}>Blog Posts</h3></Link>
        </Col>

        <Col xl={6} lg={6} md={12} sm={12} xs={12}>
          {/* BIO SECTION IS HERE! */}
        </Col>
      </Row>
     </Container>


  </Layout>
)

export default IndexPage




0 Likes

#9

If it’s a global stylesheet, like bootstrap.css, I personally tend to keep them in my index.js file, or whatever your root file is.

0 Likes

#10

hmmm, let me be more specific. You could look at the layout that I have on my blog at the top of the thread. The index page should look exactly like the pic above. I used to make Bio.js not a separate file. And I just add that section into the index page and use these to make a duo column layout,

    <Container>
      <Row>
        <Col xl={6} lg={6} md={12} sm={12} xs={12}>
          {/* BLOG POST SECTION IS HERE! */}
          <Link to="/blog" style={{textDecoration:`none`,display:`inline-block`}}><h3 style={{
          fontFamily: `'Montserrat', sans-serif`,
          fontWeight: 400,
          color: `#f47c48`,
          marginLeft:`-1rem`,
          }}>Blog Posts</h3></Link>
        </Col>

        <Col xl={6} lg={6} md={12} sm={12} xs={12}>
          {/* BIO SECTION IS HERE! */}
        </Col>
      </Row>
     </Container>

but right now when I import separate Bio.js file, I got this:

So the duo column styling went missing.

0 Likes

#11

@ husseyexplores

0 Likes

#12

Do you have a github repo link for this project?

0 Likes

#13
0 Likes

#14

Layout.js file looks off to me.
You have this code in the layout container:

render={data => (
      <>
        <Header siteTitle={data.site.siteMetadata.title} />
        <div
          style={{
            margin: `0 auto`,
            maxWidth: 960,
            padding: `0px 1.0875rem 1.45rem`,
            paddingTop: 0,
          }}
        >
          <main>{children}</main>
        <Bio />
        </div>
        <Footer />
      </>
    )}

You are rendering <Bio /> in there, AFTER main.
Are you not supposed to remove <Bio /> from your Layout.js, and render it from your index.js file inside your <Col>?

Your index JS is rendering only Layout component but Layout doesn’t have anything to render apart from empty Row and Col.

Just add your <Bio /> component where you have this comment:
{/* BIO SECTION IS HERE! */}

1 Like

#15

wow. Thank you! It worked!

If I have any questions later I might @ you here, is that okay?

1 Like

#16

Sure! I’d be glad to help whenever I can.

0 Likes