npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

use-delayed-function

v1.0.0

Published

React hook to call function with delay

Downloads

65

Readme

use-delayed-function

React hook to call a function with delay

NPM JavaScript Style Guide

This hook provides a safe way to call a function with delay and it takes care of required cleanups.

It doesn't have state and it won't cause extra rendering, so it is useful for sequential (or asynchronous) tasks where we want chain async functions on top of each others.

Install

npm install --save use-delayed-function

General structure:

  const [delayedFunction, cancelIt] = useDelayedFunction(
    originalFunction,
    delay,
    rejectOnCancel
  )

General usage format:

delayedFunction(para).then(result=>{setState(result)})

Use cases

It can be used for debouncing which simply delays all consecuative attempts to call a function and finally the last attempt runs if it persists enough time.

It is also a handy tool for applying timing logics inside react components e.g. Showing a notification for few seconds.

It is also a good choice to handle initializing stage of a component. Combination of calling functions, async task or even changing states in sequence can be handled through promise chain provided behind the scene. This kind of behaviour is mostly desirable while initializing a component.

Activities of this hook doesn't change state of the component (unless the called function set an state) so it won't cause extra rendering. The stateful version of this hook is use-delayed-state

How to use

To see deployed examples and source codes click here.

The most simplest use case is calling a function in future. In below example changeContentLater is a function that will call changeContent with delay. Note that delay is a prop (it could be a local state as well) and it dynamically controls delay value.

import React, { useRef, useEffect } from 'react'

import useDelayedFunction from 'use-delayed-function'

const SimpleExample = ({ delay = 4000 }) => {
  const divRef = useRef()

  const [changeContentLater] = useDelayedFunction(changeContent, delay)

  function changeContent(target, content) {
    target.innerHTML = content
  }

  useEffect(() => {
    changeContentLater(divRef.current, 'This is the new content')
  }, [])

  return (
    <div>
      <div ref={divRef} className='description'>
        {`This content will change after ${delay}ms from component mounting`}
      </div>
    </div>
  )
}

export default SimpleExample

In debouncing example any debounced changes in textarea appears in another paragraph.

  const [debounceChange] = useDelayedFunction(changeContent, 900)

  const [removeStyleLater] = useDelayedFunction(removeStyle, 1000)

  const [addStyleNow] = useDelayedFunction(addStyle)

  function changeContent(target, content) {
    target.innerHTML = content
    return target
  }

  function addStyle(target) {
    target.className = 'updating'
    return target
  }

  function removeStyle(target) {
    target.className = ''
  }

  function handleChange(e) {
    debounceChange(contentRef.current, e.target.value)
      .then(addStyleNow)
      .then(removeStyleLater)
  }
  return (
    <div>
      <textarea
        type='text'
        placeholder='Type something'
        onChange={handleChange}
      />
      <p ref={contentRef}></p>
    </div>
  )

As you can see in this line of code we can easily manage the timing logic that we want.

    debounceChange(contentRef.current, e.target.value)
      .then(addStyleNow)
      .then(removeStyleLater)

Details

  const [delayedFunction, cancelIt] = useDelayedFunction(
    originalFunction,
    delay,
    rejectOnCancel
  )
  • delayedFunction

    • Is a function wrapped around the originalFunction and always returns a promise.
    • It accepts and passes down arguments to the originalFunction.
    • It will resolve to return value of the originalFunction.
    • If "originalFunction" is an async function the best time for setState or DOM manipulation tasks is where it resolved. delayedFunction(para).then(doSetState)
    • Consecutive calls to this function will cancel previous unfinished calls.
  • cancelIt(doNotReject)

    • Is a function which will cancel any pending call to originalFunction.
    • If it was too late and originalFunction already fired it will break the chain and ignore its return value.
    • Calling this function will cause reject of delayedFunction if rejectOnCancel===true otherwise it leaves the promise in pending state to be removed by garbage collector.
    • If doNotReject==true it won't reject the promise even rejectOnCancel===true
  • originalFunction

    • It can be a regular or async function

    • It can accept arguments and return values

    • setState or DOM manipulation tasks can be done inside this function with no worries if they are synchronous.

    • Any setState or DOM manipulation based on async processes is forbidden inside this function because it throw errors if component was unmounted. For this purpose use this format delayedFunction(para).then(result=>{setState(result)})

  • delay

    • Is the delay before calling the originalFunction
    • Is in milliseconds
    • If not specified considered as 0
    • It could be a useRef object so delay value loaded from refObject.current
    • If it specified by a prop,state or ref, runtime value of delay will change if they change
  • rejectOnCancel

    • Is an optional boolian parameter. If not specified considered as false
    • If rejectOnCancel==true the canceled calls will reject to { message: 'Function call canceled', timestamp: Date.now() }
    • It is useful for tracking canceled calls

License

MIT © makannew