Code Monkey home page Code Monkey logo

Comments (10)

jakiestfu avatar jakiestfu commented on June 5, 2024 1

Really awesome article, Mark. I thoroughly enjoyed the writeup, really awesome to see all the twists and turns this took you through.

This is something me and my colleague were complaining about and wishing for. Days later, 1.8 was released. Great work again!

from marks-dev-blog-comments.

janne-nylund avatar janne-nylund commented on June 5, 2024 1

Thanks for the quick response!

I spun up a simple RTK demo and await listenerApi.delay() worked like a charm:

// throttle
listenerMiddleware.startListening({
  actionCreator: addIncrement,
  effect: async (action, listenerApi) => {
    listenerApi.dispatch(increment())
    listenerApi.unsubscribe()
    await listenerApi.delay(500);
    listenerApi.subscribe()
  },
});

// debounce
listenerMiddleware.startListening({
  actionCreator: addDecrement,
  effect: async (action, listenerApi) => {
    listenerApi.cancelActiveListeners()
    await listenerApi.delay(500);
    listenerApi.dispatch(decrement())
  },
});

from marks-dev-blog-comments.

josh-degraw avatar josh-degraw commented on June 5, 2024

Great post as always! So glad to have this feature finally out there!

from marks-dev-blog-comments.

Nubuck avatar Nubuck commented on June 5, 2024

Redux logic has done all this and more for years already, with the ability to work with both pre-reducer guards and post-reducer effects however you like sync, async and observables etc. Truly the most influential project I rely on. All this seems like alot of work to mimic a fraction of its power
https://github.com/jeffbski/redux-logic

from marks-dev-blog-comments.

markerikson avatar markerikson commented on June 5, 2024

@Nubuck : yes, there's definitely a lot of overlap with redux-logic here. However, that library is basically unmaintained at this point, and also has had major bundle size issues. (In fact, I filed an issue two years ago pointing out the bundle size problems, and never got a response: jeffbski/redux-logic#172 ). There's also a complete lack of TS examples or documentation.

We wanted something we could build into RTK itself, and redux-logic simply was not a viable option here.

from marks-dev-blog-comments.

janne-nylund avatar janne-nylund commented on June 5, 2024

Firstly, thank you for your excellent work with Redux Toolkit!

I'm dipping my toes into the listener middleware (I hate TS with sagas...), and I have a question regarding the effectScenarios examples. Could await listenerApi.job.delay(15) followed by listenerApi.subscribe() also be used to mimic throttling instead of setTimeout() or is there a difference?

from marks-dev-blog-comments.

markerikson avatar markerikson commented on June 5, 2024

@janne-nylund : possibly? :) Haven't thought about that in a while. I would think that you could, but I couldn't tell you off the top of my head what the exact sequence should be to make that happen.

from marks-dev-blog-comments.

markerikson avatar markerikson commented on June 5, 2024

@janne-nylund awesome!

I'll certainly say that writing that isn't as obviously intuitive as a purposely-named throttle or debounce effect :) But we did want to keep the listener middleware API pretty simple on purpose, and it's great to see that the async primitives we provided were enough to build those. And honestly you could probably pull those out into a couple little helpers, like:

async function throttle(listenerApi, timeout) {
 listenerApi.unsubscribe()
 await listenerApi.delay(timeout);
 listenerApi.subscribe()
}

async function debounce(listenerApi, timeout) {
  listenerApi.cancelActiveListeners()
  await listenerApi.delay(timeout);
}

In fact, now that I say that...

maybe what we ought to do is take these and the other relevant examples from that effects test file, and paste them into a docs section showing how to do these?

from marks-dev-blog-comments.

janne-nylund avatar janne-nylund commented on June 5, 2024

Good suggestion! This absolutely looks much cleaner:

const throttle = async (listenerApi, timeout, work) => {
  listenerApi.dispatch(work)
  listenerApi.unsubscribe()
  await listenerApi.delay(timeout);
  listenerApi.subscribe()
 }
 
 const debounce = async (listenerApi, timeout, work) => {
   listenerApi.cancelActiveListeners()
   await listenerApi.delay(timeout);
   listenerApi.dispatch(work)
 }

listenerMiddleware.startListening({
  actionCreator: addIncrement,
  effect: async (action, listenerApi) => {
    await throttle(listenerApi, 1000, increment())
  },
});

listenerMiddleware.startListening({
  actionCreator: addDecrement,
  effect: async (action, listenerApi) => {
    await debounce(listenerApi, 1000, decrement())  
  },
});

from marks-dev-blog-comments.

janne-nylund avatar janne-nylund commented on June 5, 2024

Hi again! I got some time to play with my listener demo again and started to type the throttle & debounce functions. This is what I have so far. Could the typing be improved?

import { AnyAction, ListenerEffectAPI } from '@reduxjs/toolkit';
import { AppDispatch, RootState } from './store'

type AppListenerApi = ListenerEffectAPI<RootState, AppDispatch>;

interface IListenerHelper {
  ( 
    listenerApi: AppListenerApi, 
    timeout: number, 
    work: AnyAction
  ) : Promise<void>
}

export const throttle: IListenerHelper = async ( listenerApi, timeout, work ) => {
  listenerApi.dispatch(work);
  listenerApi.unsubscribe();
  await listenerApi.delay(timeout);
  listenerApi.subscribe();
}

 
export const debounce: IListenerHelper = async ( listenerApi, timeout, work ) => {
  listenerApi.cancelActiveListeners()
  await listenerApi.delay(timeout);
  listenerApi.dispatch(work)
}

from marks-dev-blog-comments.

Related Issues (20)

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.