How to pass context to a React Thunk?

I seem to be a bit confused about how I should be utilizing thunk in my code. Initially, I thought I could use it to dispatch async actions like the example below:

app/index.ts

import { applyMiddleware, createStore } from "redux";
import thunk from "redux-thunk";
import reducer from "./reducers/index";

const store = createStore(reducer, {}, applyMiddleware(thunk));

ReactDOM.render(
   <Provider store={store}>
     <App />
   </Provider>,
   document.getElementById("root") as HTMLElement,
);

actions.ts

export interface RemoveDoneAction {
  type: TypeKeys.REMOVE_DONE;
  done: Task;
}

export const removeDone: ThunkAction<Promise<void>, Task, {}> =
 (dispatch, getState) => {
    const done = getState();
    return done.delete() // Call API
    .then(() => {        // Send Action
        const action: RemoveDoneAction = {
          type: TypeKeys.REMOVE_DONE,
          done,
        };
        dispatch(action);
    });
  };

todo.tsx

import * as React from "react";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { removeDone } from "./actions";

interface IDoneProps {
  doneList: Task[];
  dispatch: Dispatch<{}>;
}

class Done extends React.Component<IDoneProps, {}> {

  public removeFromDone = (index: number) => {
    const todo = this.props.doneList[index];

    //call thunk action!
    removeDone(this.props.dispatch, () => (todo), {}).then(() => {
      console.log("thunk then!");
    });
  }

 public render() {
    //create a item from each done
    const doneItems = this.props.doneList.map((done, i) => {
      return (
        <TodoItem
          text={done.description}
          key={i}
          index={i}
          icon="close"
          iconColor="#d67866"
          onClick={this.removeFromDone}
        />
      );
    });

    return (
      <Card title={`${this.props.doneList.length} todo${this.props.doneList.length > 1 ? "s" : ""} done`}>
        <ul>
          {doneItems}
        </ul>
      </Card>);
  }
}


export default connect((state) => {
  return { doneList: state.done };
})(Done);

Even though this approach is functional, I have realized that I'm passing the context into the state and not passing anything into extraArgs...

I'm struggling to comprehend why thunk would require access to the state given that it's simply dispatching actions to the reducers?!

I have a feeling I might be overlooking something...

Answer №1

Aha! I finally cracked the code thanks to this insightful piece...

All in all, my action creator needed a slight modification:

export const eliminateCompleted = (completed: Task): ThunkAction<Promise<void>, GlobalState, null> =>
  (dispatch, getState) => {
    return completed.delete().then(() => {
      console.log(getState());
      const action: RemoveCompletedAction = {
        type: TypeKeys.REMOVE_COMPLETED,
        completed,
      };
      dispatch(action);
    });
  };

To activate it, just call upon the action creator and let redux middleware do its magic with injecting the State.

this.props.dispatch(eliminateCompleted(task));

This adjustment definitely clarifies things...

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

Deleting specific URLs in Markdown using TypeScript

Currently, I am working with Typescript and Node v8, aiming to process markdown text and eliminate all image URLs that match specific criteria: URLs containing the term "forbidden" URLs with IP addresses I have been using the following regular expression ...

Increasing an ID number automatically using Javascript

I'm currently working on a functionality where a unique number is automatically generated whenever a new record is created. For instance, if I were to click "Create record" on a webpage, the number would auto-fill in the record ID field. Subsequently, ...

NPM Package: Accessing resources from within the package

My Current Setup I have recently developed and published an npm package in typescript. This package contains references to font files located within a folder named public/fonts internally. Now, I am in the process of installing this package into an Angul ...

The type 'ssr' is not found within the 'ResourcesConfig | LegacyConfig | AmplifyOutputs' interface. Error code: ts(2353)

I've been following a step-by-step tutorial (check it out here at 2:25:16) on creating a full stack application, but I've hit a roadblock when trying to enable SSR. import "@/styles/globals.css"; import type { AppProps } from "next ...

The npm karma phantomJS error message indicates that the undefined object is not a valid

During testing of a react-redux application using Karma, all tests were successful when run with webkit but failed when run with phantomJS. The error message displayed was: TypeError: undefined is not a constructor (evaluating 'Object.assign({} [...] ...

Retrieving information from a .json file using TypeScript

I am facing an issue with my Angular application. I have successfully loaded a .json file into the application, but getting stuck on accessing the data within the file. I previously asked about this problem but realized that I need help in specifically und ...

How can you display a set of components in React using TypeScript?

I'm currently working on rendering an array of JSX Components. I've identified two possible methods to achieve this. Method one (current approach): Create the array as an object type that stores the component properties and then build the JSX co ...

Creating a function that utilizes a default argument derived from a separate argument

Consider this JavaScript function: function foo({ a, b, c = a + b }) { return c * 2; } When attempting to add type annotations in TypeScript like so: function foo({ a, b, c = a + b }: { a?: number, b?: number, c: number }): number { return c * 2; } ...

The Angular template is throwing an error stating that c_r1.getCatType is not a valid function

Within my Angular project (version 9.1.0), I have a class structured like this: export class Contract { contractName: string; limit: number; public getCatType(): string{ if(this.limit > 0) return 'p'; return &ap ...

Tips for transforming alphanumeric characters into value ranges using Typescript

myArray = ["AB01","AB02","AB03","AB04","AB11","BC12","BC13", "SB33"]; // code snippet to create expected string: "AB01-AB04, AB11, BC12-BC13, SB33" The array contains combinations of one or two letter characters followed by two or three digits. Examples ...

Comparing Angular 2 with Angular.js, React.js, and Typescript

Hello there, I am a fresh-faced web developer looking to create a modest website for my personal use. However, my knowledge is limited when it comes to JavaScript and jQuery concepts. In order to expand my skills and build an enhanced website, I decided ...

Angularfire2 retrieve list of data with a specified number of items from the

I am facing a challenge in retrieving a specific node from my firebase database. https://i.sstatic.net/YDevB.png The technologies I am using include: "angularfire2": "^5.0.0-rc.4", "firebase": "^4.9.0", In my component code, you can find the following ...

Expand the font manually

Is there a way to define a type that represents the widened version of another type? Consider the following scenario: function times<A extends number, B extends number>(a: A, b: B): A & B; The intention behind this times function is to preserv ...

Rule in ESLint mandating return type for arrow functions

I currently have the following arrow function within my Angular project: this.httpClient.get('url').subscribe((response)=>{ }); It is important to note that ESLint should detect an error in the above code due to not specifying a return type. ...

Is it possible to find a more efficient approach than calling setState just once within useEffect?

In my react application, I find myself using this particular pattern frequently: export default function Profile() { const [username, setUsername] = React.useState<string | null>(null); React.useEffect(()=>{ fetch(`/api/userprofil ...

Identifying one of the two possible return types automatically

In my code, there is a function named isDone() that will return data from either an array of hashes or a dictionary of hashes: public async isDone() { this.startDelayedTasks(); await Promise.all(this._tasks); const hadErrors = this._failed.length &g ...

Why does VSCode open a React app in Edge instead of Chrome?

Recently, I began a new project using the react-create-app template with typescript. However, when I run npm run dev, it unexpectedly opens in the Edge browser instead of Chrome. Does anyone know how to make it open in Chrome instead? ...

A guide on parsing a stringified HTML and connecting it to the DOM along with its attributes using Angular

Looking for a solution: "<div style="text-align: center;"><b style="color: rgb(0, 0, 0); font-family: "Open Sans", Arial, sans-serif; text-align: justify;">Lorem ipsum dolor sit amet, consectetur adipiscing e ...

Issues may arise in TypeScript when you are working with an array of objects along with other properties within a type

I am encountering an issue with an object structure similar to the one below: let Obj = { ['0'] : { mode: 'x' }, getMode: () => 'x' } The problem arises when I attempt to create a type definition as shown here: type Obj = ...

Why is there an error when trying to assign Type '{}' in generics typescript?

I'm having trouble understanding why this code is causing an error. The error message says - Type '{}' is not assignable to type 'Keys<T>'. type Keys<T extends string|symbol>={ [key in T]: string; }; const foo = < ...