Utilize a function to operate on every item within an object's exports and then export with an identical name

Hey, I'm struggling to explain this but let me try to make it clear:

LoginDispatch.ts

const useLoginDispatch = () => {
  const dispatch = useDispatch()

  const setLoginScreen = (screen: LoginScreen) => {
    dispatch(loginActions.setLoginScreen(screen))
  }

  const setRegisterError = (message: string) => {
    dispatch(loginActions.setRegisterError(message))
  }

  // It feels like a lot of repetitive code writing dispatch() for each action. Is there a way to automate this process?
  // Take note that the exports below match the names in loginActions

  return { setLoginScreen , setRegisterError }
}

All I'm doing is using dispatch() with every function exported from loginActions. To change the login screen, I simply type:

LoginComponent.tsx

const loginDispatch = useLoginDispatch()
loginDispatch.setLoginScreen(LoginScreen.Register)

Instead of:

LoginComponent.tsx

const dispatch = useDispatch()
dispatch(loginActions.setRegisterError(message))

I could manually continue adding functions to LoginDispatch.ts, but with so many actions in my app, is there a way to automatically map dispatch to all of the exports in LoginActions.ts and export them with their original function names?

If you want to take a look, here's my Actions.ts file. (Every export follows the same structure, except for parameters and return types)

Actions.ts

export const setLoginScreen = (screen: LoginScreen): LoginActionTypes => ({
  type: LoginActions.SET_LOGIN_SCREEN,
  payload: screen
})

export const setRegisterError = (message: string): LoginActionTypes => ({
  type: LoginActions.SET_REGISTER_ERROR,
  payload: message
})

NOTE: I am leaving Actions.ts unchanged because other functions (like put() in sagas) also rely on these functions.

Answer №1

Here is a helpful tip for you:

const useLoginDispatch = () => {
  const dispatch = useDispatch();
  //Use useMemo to store the result and create it only once during mounting
  return useMemo(
    () =>
      //Create a new object from entries
      Object.fromEntries(
        //Extract object entries from loginActions
        Object.entries(loginActions)
          .filter(
            //Filter out only the properties that are functions
            ([, value]) => typeof value === 'function'
          )
          .map(([key, value]) => [
            key,
            //Create a new function that will dispatch the result of the original function call
            (...args) => dispatch(value(...args)),
          ])
      ),
    [dispatch]
  );
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Can you point me to the location where the 'req' parameter is specified?

I've been exploring a new authentication approach detailed in this article. One issue I'm encountering is locating where the req parameter is declared in the snippet below. It seems like my code won't compile because this parameter isn&apos ...

Encountering compilation errors with TypeScript files in Angular 2 while using Visual Studio 2017

Currently, I am in the process of developing an Angular 2 application Here is a snippet of the TypeScript code that I have written: import { Component } from 'angular2/core'; @Component({ selector: 'my-app', template: ' &l ...

What is the most efficient way to prevent state store data from accumulating in a Redux component each time I access it through React Router?

Recently, I started learning about redux and its application in web development. As part of a course, I decided to create a standard website using the wordpress API along with Redux. While I understand that redux is typically used for more complex projects ...

The error message "Type 'IPromise<{}>' is not compatible with type 'IPromise<TemplatesPagingModel>' in typescript version 2.8.0" is displayed

Currently, I am working on an AngularJS framework (version 1.5.8) with the latest TypeScript files (version 2.8.0). However, after updating to the most recent TypeScript version, the code below is not compiling. Implementation of Angular interface: inter ...

Rejecting the request by clicking a button

While switching to a menu, I retrieve data from the API. As the pending data is still loading in DevTools, I click on the Filter button to search for additional data. The data I am searching for appears in my table. However, once the pending data finishes ...

Ways to pass state between different Rekit modules?

After discovering Rekit, I was impressed with its ability to simplify the learning process for React and Redux. However, its specific way of organizing things has raised questions about the best practice for sharing state between different features in an a ...

Vue 3 - Compelled to utilize any data type with computedRef

Recently, I've been diving into Vue/Typescript and encountered a puzzling error. The issue revolves around a class named UploadableFile: export class UploadableFile { file: File; dimensions: Ref; price: ComputedRef<number>; ... constr ...

How can I make the snackbar open multiple times in a row?

Check out this codesandbox I created to show an issue. When you click the button, a MUI snackbar opens. However, if you close it and try to reopen it, nothing happens. Do you think the problem is related to how I'm using hooks? Explore the sandbox h ...

Retrieve the current state of a component and save it to the Redux store

What is the best method to retrieve the most updated state of a React component after all state changes have been completed, and then store this object in Redux? How can I effectively obtain the latest state and trigger an action (with a duplicate of the ...

Unable to locate the name 'JSON' in the typescript file

I have been working on an angular application where I have implemented JSON conversion functionalities such as JSON.stringify and JSON.parse. However, I encountered an error stating 'Cannot find name 'JSON''. Furthermore, there is anoth ...

The dynamic fusion of Typescript and Angular 2 creates a powerful

private nodes = []; constructor(private nodeService: NodeService) {} this.nodeService.fetchNodes('APIEndpoint') .subscribe((data) => { this.nodes.push(data); }); console.log(this.nodes) This ...

Unable to initiate ngModelChange event during deep cloning of value

I've been struggling to calculate the sum of row values, with no success. My suspicion is that the issue lies in how I am deep cloning the row values array when creating the row. const gblRowVal1 = new GridRowValues(1, this.color, this.headList ...

Understanding the Purpose of the Pipe Function in Angular 2 and Typescript Observables

Recently, I encountered a situation where I needed to accept an Observer parameter in a function written in Typescript. I struggled to find a solution, reminding me of working with a delegate parameter in C#. The specific scenario involved adding a bookend ...

Even with manual installation, the npm package still encounters dependency errors

Having trouble implementing the Imgur package from NPM into my Angular web app. The installation and import seemed to go smoothly, but when initializing a variable with the package, I encounter compile errors pointing to missing dependencies like 'cry ...

Creating a one-dimensional array without utilizing the FlatMap method

My objective is to access the 'values' array of the 'model' array separately. However, the 'flatMap' function is not available in my Angular application without adding "esnext" to the tsconfig.json file. I am exploring alterna ...

Developing an S3 Bucket policy with Pulumi

I am currently working on setting up an S3 bucket and a corresponding S3 policy using Pulumi with TypeScript. However, during the pipeline execution, I encountered the following error in the test stage: expect(received).toEqual(expected) // deep equality - ...

I'm looking to extract plugin details, such as information about the plugin and its license type, from the package.json file using React with types

There is a specific requirement for our project. Our project utilizes React with Typescript. We need to display plugin information such as version, git URL, and readme from the package.json file on a webpage. Additionally, we must ensure that the page upd ...

Injectable error occurred while injecting one @Injectable() into another

I'm encountering an issue with Angular2 Dependency Injection. When attempting to inject one class into another, I am receiving the following error: Error Message: "Cannot resolve all parameters for 'ProductService'(undefined). Make sure tha ...

Tips on getting the dropdown value to show up on the header when it changes using Angular 2 and TypeScript

I need assistance with creating a dropdown field in Angular2. When the user selects "car", I want it to display beside the heading. Can anyone provide guidance on how to achieve this? HTML: <h1>Heading <span *ngFor= "let apps of apps">({{apps ...

MUI Select component not displaying top border

Can anyone help me understand why the select field is behaving this way? I'm new to the project and suspect that someone may have made changes to it. https://i.sstatic.net/pB6Sx.png <mui.FormControl style={{ width: '598px' }}> ...