Giter Site home page Giter Site logo

gatsby-with-query's Introduction

Hi, I'm Kevin Han. I'm a frontend engineer.

gatsby-with-query's People

Contributors

kevinydhan avatar

Watchers

 avatar  avatar

gatsby-with-query's Issues

WithQueryHOC type definition expects all props from parent component

In the following type definition for WithQuery:

import { FunctionComponent } from 'react'

type WithQuery = <Props = Record<string, never>>(
  Component: FunctionComponent<Props>,
  useQueryHook: () => Props
) => FunctionComponent<ReturnType<typeof useQueryHook>>

useQueryHook()'s return type should be one of the following:

  1. all of the component's props
  2. a subset of the component's props

In addition, the parameter for the WithQueryHOC component should also be one of the two cases:

  1. all of the component's props
  2. a subset of the component's props


Considering these two requirements, a possible type definition would be to use Partial<T> for both useQueryHook()'s return value and the parameter for the WithQueryHOC component:

import { FunctionComponent } from 'react'

type WithQuery = <Props = Record<string, never>>(
  Component: FunctionComponent<Props>,
  useQueryHook: () => Partial<Props>
) => FunctionComponent<ReturnType<typeof useQueryHook>>

However, this poses the problem where calling React.createElement() with partial props will trigger a TypeScript warning.

Provide support for Gatsby's StaticQuery

A possible feature would be to provide support for <StaticQuery>. However, the immediate issue is that it seems unnecessary to utilize <StaticQuery> as demonstrated below:

// App.tsx
import React, { FunctionComponent } from 'react'
import { graphql, StaticQuery } from 'gatsby'
import withQuery from 'gatsby-with-query'

interface AppProps {
  title: string
  description: string
}

export const App: FunctionComponent<AppProps> = ({ title, description }) => (
  <main>
    <h1>{title}</h1>
    <p>{description}</p>
  </main>
)

const query = graphql`
  query GetSiteMetadata {
    site {
      siteMetadata {
        title
        description
      }
    }
  }
`

// Possibly something like this? 
export default withQuery<AppProps>(() => (
  <StaticQuery query={query}>
    {(queriedProps) => <App {...queriedProps} />}
  </StaticQuery>
))

Expose the type definition for the receivedProps parameter in useQueryHook

If a developer wanted to create a standalone React query hook, they will most likely have to explicitly type their hook to utilize IntelliSense for receivedProps:

// receivedProps will be type `any`
const useGetSiteMetadataQuery = (receivedProps) => {
  const queriedProps = useStaticQuery(query)
  return {
    ...queriedProps.site.siteMetadata,
    ...receivedProps,
  }
}

Approach 1: Providing a type definition for useQueryHook

import type { WithQueryHook } from 'gatsby-with-query'
import type { AppProps } from './App.d'

const useGetSiteMetadataQuery: WithQueryHook<AppProps> = (receivedProps): AppProps => {
  const queriedProps = useStaticQuery(query)
  return {
    ...queriedProps.site.siteMetadata,
    ...receivedProps,
  }
}

Approach 2: Providing a type definition for receivedProps

import type { WithQueryReceivedProps } from 'gatsby-with-query'
import type { AppProps } from './App.d'

const useGetSiteMetadataQuery = (receivedProps: WithQueryReceivedProps<AppProps>): AppProps => {
  const queriedProps = useStaticQuery(query)
  return {
    ...queriedProps.site.siteMetadata,
    ...receivedProps,
  }
}

Pass receivedProps into useQueryHook()

Currently, the WithQueryHOC component is overwriting duplicate props.<key>:

const withQuery: WithQuery = (Component, useQueryHook) => {
  const WithQueryHOC: ReturnType<WithQuery> = (receivedProps) => {
    const queriedProps = useQueryHook()
    return createElement(Component, {
      ...queriedProps,
      ...receivedProps, // Any duplicate keys are overwritten
    })
  }
  // ...
}

This may or may not be a behavior that developers want. Instead, receivedProps can be passed as an argument to useQueryHook() and the developer can manage their component's props in the useQueryHook() function:

// Component file

const App = () => {
  // ...
}

export default withQuery<AppProps>(App, (receivedProps) => {
  const queriedProps = useStaticQuery(query)
  
  // Do some logic with received and queried props
  
  return {
    ...queriedProps,
    ...receivedProps,
  }
})


Questions

  • Will the type definitions need to adapt to whether the developer chooses to utilize receivedProps in their query hook?

Find a way for withQuery() to infer the type definition for the component's props

Currently, withQuery() is a generic function. The developer has to explicitly define their prop's type definition:

export default withQuery<AppProps>(App, () => {
  // ...
})

It would be nice if withQuery() can automatically infer the type definition for the component's props:

interface AppProps {
  title: string
  description: string
}

const App: FunctionComponent<AppProps> = ({ title, description }) => (
  <main>
    <h1>{title}</h1>
    <p>{description}</p>
  </main>
)

export default withQuery(App, (receivedProps) => {
  // receivedProps is either a subset of AppProps or AppProps
})

I can possibly utilize Parameters<T> to infer the component's props.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.