Skip to content

Latest commit

 

History

History
294 lines (226 loc) · 6.91 KB

README.md

File metadata and controls

294 lines (226 loc) · 6.91 KB

Frontend Essentials

npm package npm downloads

npm i frontend-essentials

React Components

LazyRender

Lazily renders a large list of items:

<LazyRender items={notes} batch={20}>
  {({ _id, title, content, date }) => <Note key={_id} title={title} content={content} date={date} />}
</LazyRender>

Media

Conditionally renders a component when certain media queries are matched:

<Media query="(max-width: 768px)">
  <Menu />
</Media>

When an array is passed as query, queries will have an OR relationship when matching:

// matches when width is at most 480px or at least 1200px
<Media query=["(max-width: 480px)", "(min-width: 1200px)"]>
    <Menu />
</Media>

Meta

Sets meta properties for title, description and Open Graph:

<Meta
  title="Frontend Essentials"
  description="A set of useful functions, components and hooks."
  image="https://my-website.com/icons/og-icon.png"
/>

Results in:

<title>Frontend Essentials</title>
<meta name="description" property="description" content="A set of useful functions, components and hooks." />
<meta name="og:type" property="og:type" content="website" />
<meta name="og:url" property="og:url" content="https://my-website.com" />
<meta name="og:title" property="og:title" content="Frontend Essentials" />
<meta name="og:image" property="og:image" content="https://my-website.com/icons/og-icon.png" />

React Hooks

useAxios

Handles http requests easily:

const { loading, status, error, data, activate } = useAxios({
  method: 'get',
  url: 'https://example.com/v1/items',
  onSuccess: ({ data }) => console.log(data),
  onError: ({ error }) => console.error(error)
})

Initial request can be skipped and triggered manually:

const { loading, status, error, data, activate } = useAxios({
  method: 'get',
  url: 'https://example.com/v1/items',
  manual: true,
  onSuccess: ({ data }) => console.log(data)
})

setTimeout(activate, 3000)

When specifying a UUID, response data will be persisted between rerenders:

const { loading, status, error, data, activate } = useAxios({
  method: 'get',
  url: 'https://example.com/v1/items',
  uuid: 'items',
  onSuccess: ({ data }) => console.log(data)
})

Refetches can be prevented during rerenders:

const { loading, status, error, data, activate } = useAxios({
  method: 'get',
  url: 'https://example.com/v1/items',
  uuid: 'items',
  immutable: true,
  onSuccess: ({ data }) => console.log(data)
})

Null response keys can be purged:

const { loading, status, error, data, activate } = useAxios({
  method: 'get',
  url: 'https://example.com/v1/items',
  purgeNull: true,
  onSuccess: ({ data }) => console.log(data)
})

Response keys can be transformed to camelCase:

const { loading, status, error, data, activate } = useAxios({
  method: 'get',
  url: 'https://example.com/v1/items',
  camelCased: true,
  onSuccess: ({ data }) => console.log(data)
})

Get axios instance:

import { axios } from 'frontend-essentials'

axios.defaults.withCredentials = true

useFetch

Similar to useAxios but with native fetch's API:

const { loading, response, status, error, data, activate } = useFetch('https://example.com/v1/items', {
  mode: 'no-cors',
  onSuccess: ({ data }) => console.log(data)
})

useMedia

Returns a media queries object containing boolean matches for each passed query:

const { mobile, tablet } = useMedia({
  mobile: '(max-width: 480px)',
  tablet: '(min-width: 481px) and (max-width: 1199px)'
})

const getDescription = () => {
  if (mobile) return 'Hello'
  if (tablet) return 'Hello Mr.'
  return 'Hello Mr. Smith'
}

return <div>{getDescription()}</div>

useObjectState

Makes working with form state easier by returning a setState that shallowly merges state like this.setState does.
In addition, it returns a third resetState function that reverts the form to its initial state:

const [form, setForm, resetForm] = useObjectState({
  name: '',
  age: 18,
  address: ''
})

return (
  <form>
    <input value={form.name} onChange={event => setForm({ name: event.target.value })} />
    <input type="number" value={form.age} onChange={event => setForm({ age: event.target.value })} />
    <input value={form.address} onChange={event => setForm({ address: event.target.value })} />

    <button type="button" onClick={resetForm}>
      Reset
    </button>
  </form>
)

usePersistState

Allows you to keep your current state between rerenders:

const [posts, setPosts] = usePersistState('posts', [])

// will store the state in memory for the next mount
setPosts([
  { id: 1, title: 'First', content: 'Lorem' },
  { id: 2, title: 'Second', content: 'Ipsum' }
])

usePersistObjectState

The combination of usePersistState and useObjectState:

const [form, setForm, resetForm] = usePersistObjectState(
  'student',
  {
    name: '',
    age: 18,
    address: ''
  },
  { localStorage: true }
)

useProgressiveImage

Returns a low quality image source until a higher resolution image is fetched:

const [src, blur] = useProgressiveImage(lowQualitySrc, highQualitySrc)

return <img style={{ filter: blur ? 'blur(20px)' : 'none' }} src={src} />

useTransitionNavigate

Delays React Router's navigation until the target page is rendered:

const navigate = useTransitionNavigate()

<NavLink
    to='home'
    onClick={event => {
    event.preventDefault()
    navigate('home')
    }}
>
    Home
</NavLink>

Utility Functions

lazyPrefetch

Prefetches a lazily loaded React module:

const Login = lazyPrefetch(() => import('pages/Calendar'))

Note: the prefetch occurs 250ms after the load event. If there are images in the DOM, the prefetch will occur only after they are downloaded.