Reputation: 177
I am wanting to create a data file for my project instead of having everything in the one file, however I am using React hooks to load in images. This becomes a problem when I want to have everything in separate files. The code gives me the 'Invalid hook call' message which I understand why it is wrong, but can't figure out how to get it to work for me.
EventData.js
import React from "react"
import Image from "gatsby-image"
import { graphql, useStaticQuery } from "gatsby"
const getImages = graphql`
{
btu: file(relativePath: { eq: "eventImage/btu.jpeg" }) {
childImageSharp {
fixed(height: 120, width: 500) {
...GatsbyImageSharpFixed_withWebp_tracedSVG
}
}
}
}
`
const data = useStaticQuery(getImages)
export const details = [
{
id: 1,
img: <Image fixed={data.btu.childImageSharp.fixed} />,
date: "2 Oct 2020",
distance: "30km - 160km",
name: "Brisbane Trail Ultra",
location: "Brisbane, QLD",
},
]
EventCalendar.js
const EventCalendar = () => {
return (
<Layout>
<section>
{details.map(details => {
return <EventCard key={details.id} {...details}></EventCard>
})}
</section>
</Layout>
)
}
Upvotes: 2
Views: 10756
Reputation: 4985
You have to define a custom hook, which looks something like this in your case:
import React from "react"
import Image from "gatsby-image"
import { graphql, useStaticQuery } from "gatsby"
const getImages = graphql`
{
btu: file(relativePath: { eq: "eventImage/btu.jpeg" }) {
childImageSharp {
fixed(height: 120, width: 500) {
...GatsbyImageSharpFixed_withWebp_tracedSVG
}
}
}
}
`;
export function useDetails() {
const data = useStaticQuery(getImages);
return [
{
id: 1,
img: <Image fixed={data.btu.childImageSharp.fixed} />,
date: "2 Oct 2020",
distance: "30km - 160km",
name: "Brisbane Trail Ultra",
location: "Brisbane, QLD",
},
];
}
To define custom hooks, define a function, which returns your desired values. In this function you can all hooks available from the react API.
Then in your main file write
const EventCalendar = () => {
const details = useDetails();
return (
<Layout>
<section>
{details.map(detail => {
return <EventCard key={details.id} {...detail}></EventCard>
})}
</section>
</Layout>
)
}
Upvotes: 2
Reputation: 2104
Only Call Hooks from React Functions Don’t call Hooks from regular JavaScript functions. Instead, you can:
✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page). Another thing: Inside the map, you should change details to detail because is an item
const EventCalendar = () => {
return (
<Layout>
<section>
{details.map(detail => {
return <EventCard key={details.id} {...detail}></EventCard>
})}
</section>
</Layout>
)
}
You can read about hook is here: https://reactjs.org/docs/hooks-rules.html
My suggestion is you can wrap it into component like that:
const ImageHook = () => {
const data = useStaticQuery(getImages)
return <Image fixed={data.btu.childImageSharp.fixed}/>
}
export const details = [
{
id: 1,
img: <ImageHook />,
date: "2 Oct 2020",
distance: "30km - 160km",
name: "Brisbane Trail Ultra",
location: "Brisbane, QLD",
},
]
Upvotes: 0