TypeScript and Redux mapDispatchToProps are not in sync

Below is my React component written in TypeScript:

import React from 'react';
import {connect, ConnectedProps} from 'react-redux';
import logo from './assets/logo.png';
// import { Counter } from './features/counter/Counter';
import './App.css';

import {IApplicationState} from './features/application/reducers';

const mapStateToProps = (application: IApplicationState) => {
  const applicationComposite = application.applicationComposite;

  return {applicationComposite};
}
const connector = connect(mapStateToProps);
type PropsFromRedux = ConnectedProps<typeof connector>

interface Props extends PropsFromRedux {};

class App extends React.Component<Props> {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <span>
            <span>Attractora </span>
            {this.props.applicationComposite && <span>{this.props.applicationComposite.content}</span>}
          </span>
        </header>
      </div>
    );
  }
}

export default connector(App);

I am encountering an issue where the value of applicationComposite is always undefined, despite having an initial state value set in the reducer.

Upon debugging, I discovered that

mapStateToProps(application: IApplicationState)
correctly receives the value of applicationComposite as
application.application.applicationComposite
. However, when I attempt to assign
applicationComposite = application.application.applicationComposite
, it throws the following error:

Property 'application' does not exist on type 'IApplicationState'.

I have followed a tutorial on manually typing connect, but I am unable to identify where I might be making a mistake.

UPDATE

This is how my root reducer looks like:

import {combineReducers} from 'redux';
import application from '../features/application/reducers';

const rootReducer = combineReducers({
  application,
});

export default rootReducer;

And here is my application reducer:

import { Dictionary } from '@reduxjs/toolkit';
import { ActionInterface } from '../generals';
import {
  FETCH_APPLICATION_COMPOSITE_SUCCESS,
  SET_CURRENT_APPLICATION_COMPONENT
} from './actions';

export interface IApplicationState {
  applicationComposite: any,
  currentApplicationComponent: string | null,
}

const INIT_STATE = {
  applicationComposite: {content: 'test_content'},
  currentApplicationComponent: null
}

export default (state=INIT_STATE, action: ActionInterface) => {
  switch(action.type) {
    case FETCH_APPLICATION_COMPOSITE_SUCCESS: {
      return {
        ...state,
        //@ts-ignore: Object is possibly 'undefined'
        applicationComposite: action.payload.applicationComposite
      }
    }
    case SET_CURRENT_APPLICATION_COMPONENT: {
      return {
        ...state,
        //@ts-ignore: Object is possibly 'undefined'
        currentApplicationComponent: action.payload.applicationComponent
      }
    }
    default: {
      return state;
    }
  }
}

Answer №1

It appears that you may be overlooking the need to use the root state type within your mapStateToProps function.

In Redux, the application is just a part of the overall state, meaning you cannot directly access the application state in the mapStateToProps() function. To remedy this, it's necessary to define a root state type that acts as a central hub for all states.

export interface IRootState {
    application: IApplicationState
}

const rootReducer = combineReducers<IRootState>({
  application,
});

const mapStateToProps = (rootState: IRootState) => {
  const applicationComposite = rootState.application.applicationComposite;

  return {applicationComposite};
}

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

The type 'string' cannot be assigned to the type '"GET" | "get" | ...'

In my custom hook, I utilize the axios library for making requests: const useCustomHook = ({ endPoint = "", method = "GET", options = {} }) => { const [data, setData] = useState([]); const [request, setRequest] = useState<AxiosRequestConfig> ...

Ways to determine the types of props received by a function when the arguments vary for each scenario?

I have a specialized component that handles the majority of tasks for a specific operation. This component needs to invoke the onSubmit function received through props, depending on the type of the calling component. Below is an example code snippet show ...

Framer Motion's AnimatePresence feature fails to trigger animations when switching between pages

I'm running into issues with the Framer Motion library, specifically with the AnimatePresence transition. I've managed to make it work in normal situations, but when I encapsulate my Routes within a custom implementation, the exit animation fails ...

React TypeScript Context - problem with iterating through object

Can someone please help me with an error I am encountering while trying to map an object in my code? I have been stuck on this problem for hours and despite my efforts, I cannot figure out what is causing the issue. Error: const categoriesMap: { item: ...

The Angular Ivy strictTemplates error message states that the type 'Event' cannot be assigned to the type 'InputEvent' parameter

I'm feeling lost trying to figure out what's wrong with this code snippet: <input #quantity type="number" matInput formControlName="quantity" (input)="onQuantity($event, i)" placeholder="Quantity"/> onQuantity(event: InputEvent, i: number ...

RxJS BehaviorSubject allows you to retrieve the current value or obtain a new one depending on a specific condition

I am managing a subject that consumers subscribe to: private request$: Subject<Service> = new BehaviorSubject(null); Upon initialization, my components utilize this function: public service(id: number): Observable<Service> { return this. ...

Strange activities observed during the management of state in react hooks, where the splice() function ends up eliminating the

My current setup involves maintaining a state to handle the addition of new JSX elements: const [display, setDisplay] = useState<IDisplay>({ BookingFormDropDown: [], } ); I have a function in onClick() which adds an elem ...

In the Vercel production environment, when building Next.js getStaticPaths with URL parameters, the slashes are represented as %

I've encountered an issue while implementing a nextjs dynamic route for my static documentation page. Everything works perfectly in my local environment, and the code compiles successfully. However, when I try to access the production URL, it doesn&ap ...

What could be causing my Page to not update when the Context changes?

In my Base Context, I store essential information like the current logged-in user. I have a User Page that should display this information but fails to re-render when the Context changes. Initially, the Context is empty (isLoaded = false). Once the init fu ...

Typescript fetch implementation

I've been researching how to create a TypeScript wrapper for type-safe fetch calls, and I came across a helpful forum thread from 2016. However, despite attempting the suggestions provided in that thread, I am still encountering issues with my code. ...

Node.js allows for keeping pipe and sockets open even after streaming an HTTP response

My current challenge involves streaming data from an HTTP response to a cloud storage provider within an internal service. const response = await request<Readable>({ headers: httpOpts?.headers, data: httpOpts?.data, url, method, responseTyp ...

Tips for Simplifying Complex Switch Cases with Object Literals in TypeScript

I have a unique situation where I need to switch between two functions within an object literal. One function takes two numerical arguments, "A" and "B", while the other function only takes a single string argument, "C". My TypeScript code showcases my di ...

Factory function in Angular for translating using arrow syntax

When I include TranslateModule using the following code: TranslateModule.forRoot({ loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, deps: [HttpClient] } }) where export function HttpLoaderFactory(http: H ...

How to import a page from a different component in the Next.js application router

I am currently utilizing the Next.js app router and have organized my folders as follows: app/ ├─ /companies/ │ ├─ page.tsx ├─ /administrators/ │ ├─ page.tsx My objective is to import the companies/page.tsx component into the admini ...

Question about TypeScript annotations: arrays containing key-value pairs

Is there an explanation for why this issue occurs in VSCode? interface Point { x: number; y: number; } let grid: [key: number, value: [key: number, value: Point]]; // ... // Accessing an object of type number | [key: number, value: Point] var c ...

Issue: The observer's callback function is not being triggered when utilizing the rxjs interval

Here is a method that I am using: export class PeriodicData { public checkForSthPeriodically(): Subscription { return Observable.interval(10000) .subscribe(() => { console.log('I AM CHECKING'); this.getData(); }); } ...

Leveraging async/await in Firebase functions along with the once() method

Recently diving into the world of TypeScript, I've been navigating my way through with relative ease. However, I've encountered a perplexing issue while working with async/await. The problem lies within this code snippet - the 'await' ...

Issue encountered during rendering: "TypeError: Attempting to access property '_t' of an undefined object" while running a Unit Test using Jest

I spent hours troubleshooting a unit test for my Vue.js component, but no matter how much I searched the internet, I kept encountering this error: console.error node_modules/vue/dist/vue.runtime.common.dev.js:1884 TypeError: Cannot read property ' ...

Tips on filtering an array in a JSON response based on certain conditions in Angular 7

Looking to extract a specific array from a JSON response based on mismatched dataIDs and parentDataIDs using TypeScript in Angular 7. { "data":[ { "dataId":"Atlanta", "parentDataId":"America" }, { "dataId":"Newyork", ...

Updating the state on change for an array of objects: A step-by-step guide

In my current scenario, I have a state variable defined as: const [budget, setBudget] = React.useState<{ name: string; budget: number | null }[]>(); My goal is to update this state by using a TextField based on the name and value of each input ...