Unable to access component properties through react-redux

Context: A React Native application utilizing Redux for managing complexity.

Versions:

  • typescript v3.0.3
  • react-native v0.56.0
  • redux v4.0.0
  • @types/react-redux v6.0.9
  • @types/redux v3.6.0

Issue: The main JSX component in my app is unable to access properties (errors detailed in comments).

The primary file:

//app.tsx
export default class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <MainRedux ownProp="as"/> //[1]: Type '{ ownProp: string; }' is not assignable to type 'Readonly<AllProps>'. Property 'appPermissions' is missing in type '{ ownProp: string; }'.
      </Provider>
    );
  }
}

and the secondary file:

//MainRedux.tsx
export interface ApplicationState { //originally in another file
  appPermissions: AppPermissionsState;
  //...
}

type StateProps = ApplicationState; //alias appPermissions is in the Application State

interface DispatchProps {
  getPermissions: typeof getPermissions;
  //...
}

interface OwnProps {
  ownProp: string;
}

type AllProps = StateProps & DispatchProps & OwnProps;

export class MainRedux extends React.Component<AllProps> {
  constructor(props: AllProps) {
    super(props);
    props.getPermissions(); //[2]: TypeError: undefined is not a function (evaluating 'props.getPermissions()')
  }
  //...
} //class

//...
const mapStateToProps: MapStateToProps<
  StateProps,
  OwnProps,
  ApplicationState
> = (state: ApplicationState, ownProps: OwnProps): StateProps => {
  return state;
};

const mapDispatchToProps: MapDispatchToPropsFunction<
  DispatchProps,
  OwnProps
> = (dispatch: Dispatch<AnyAction>, ownProps: OwnProps): DispatchProps => ({
  getPermissions: bindActionCreators(getPermissions, dispatch)
  //...
});

export default connect<StateProps, DispatchProps, OwnProps, ApplicationState>(
  mapStateToProps,
  mapDispatchToProps
)(MainRedux);

Error [1] occurs during compilation, while error [2] is a runtime issue.

Seeking assistance on identifying the problems. Appreciate your help.

Edit: Added debug information into mapStateToProps and mapDispatchToProps, but it seems like connect is not calling them. There's a possibility that even the connect function itself is not being triggered.

Answer №1

Looks like the state to props mapping may need some adjustments.

To test this, you can add the following code to your MapStateToProps function:

const mapStateToProps: MapStateToProps<StateProps,OwnProps,ApplicationState> = 
(state: ApplicationState, ownProps: OwnProps): StateProps => {
  return {test : "hello"}
};

Check if you can see test in your console.log(this.props) within your componentDidMount().

If it works, you will need to map your object keys accordingly:

return {
 propkey1 : state.propkey1,
 propkey2 : state.propkey2
 .... etc
}

However, without seeing the full codebase, it's difficult to provide a definitive solution.

Answer №2

Upon reading @MattMcCutchen's comment, it struck me. The connect function actually returns a decorated class that is no longer the original component class. For example, instead of MyComponent, it becomes something entirely different like

let ConnectedMyCommponent = connect(...)
. This new class can then be imported as
import {ConnectedMyComponent} from '.\...'
within the file containing the parent Provider tag, such as
<Provider><ConnectedMyComponent></Provider>
.

My mistake lies in not updating the import statement during code refactoring, where I neglected to change from import {MainRedux} from './...' to import MainRedux from './...'.

A helpful tip for those transitioning from vanilla react-native to redux react-native: remember to remove any export keywords from your component class definition, as connect will handle the creation of a new class. This simple adjustment can save you from spending too much time deciphering confusing error messages.

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 function Event.target.value is coming back as null

I've been working on creating a timer window, and I've set up a separate component for it. However, I'm facing an issue with passing the time from the main component to the child component. The problem lies in the fact that the state of the ...

Encountering a service error that results in the inability to read properties of undefined when passing a method as a

Whenever I attempt to pass a service function as a parameter to another function, an error 'Cannot read properties of undefined myService' occurs during execution. However, calling this.myService.method() individually works perfectly fine without ...

Having trouble getting ng-click to function properly in TypeScript

I've been struggling to execute a function within a click function on my HTML page. I have added all the TypeScript definition files from NuGet, but something seems to be going wrong as my Click Function is not functioning properly. Strangely, there a ...

Is there an issue with the newline character ` ` not functioning properly in TypeScript when used with the `<br/>` tag?

Having trouble with using New Line '\n' ' ' in Typescript Here is an example of my typescript code: this.custPartyAddress = estimation.partyName + ',' + '\n' + estimation.partyAddress + ',' + ...

Timestamps are no longer recognized in Highstock charts once data has been added

In my highstock chart, I am pulling data from a REST api and everything appears correct. However, there is no data available between 19:00 and 05:00. I would like this absence of data to be reflected in the chart without cropping out that time span from th ...

React not displaying wrapped div

I am facing an issue with my render() function where the outer div is not rendering, but the inner ReactComponent is displaying. Here is a snippet of my code: return( <div style={{background: "black"}}> <[ReactComponent]> ...

Exploring the depths of Angular8: Utilizing formControlName with complex nested

After dedicating numerous hours to tackle this issue, I finally came up with a solution for my formGroup setup: this.frameworkForm = this.formBuilder.group({ id: [null], name: ['', Validators.required], active: [true], pa ...

Expanding the header in Ionic 3 with a simple click event

I have successfully implemented an Expandable Header in Ionic 3 following a tutorial from Joshmorony. The header expands perfectly on scroll, as you can see in this GIF: However, I am facing an issue where I want to expand the header on click instead of o ...

Ways to encourage children to adopt a specific trait

Let's discuss a scenario where I have a React functional component like this: const Test = (props: { children: React.ReactElement<{ slot: "content" }> }) => { return <></> } When a child is passed without a sl ...

What is the reason behind the ability to reassign an incompatible function to another in TypeScript?

I discovered this question while using the following guide: https://basarat.gitbooks.io/typescript/content/docs/types/type-compatibility.html#types-of-arguments. Here is an example snippet of code: /** Type Heirarchy */ interface Point2D { x: number; y: ...

Nearly every category except for one from "any" (all varieties but one)

In Typescript, is it feasible to specify a type for a variable where the values can be any value except for one (or any other number of values)? For instance: let variable: NOT<any, 'number'> This variable can hold any type of value excep ...

TypeScript enabled npm package

I am currently developing a npm module using TypeScript. Within my library, I have the following directory structure: . ├── README.md ├── dist │ ├── index.d.ts │ └── index.js ├── lib │ └── index.ts ├── ...

Modify the URL and show the keyword utilized in a search module

Does anyone know how to update the URL in a search bar? I'm using Redux to display search results, but the URL remains the same. How can I make the URL show the keyword being searched, like this: http://localhost/seach?q=keyword ...

Angular 6 implement a waiting function using the subscribe method

I need to make multiple calls to a service using forEach, where each call depends on the completion of the previous one. The code is as follows: itemDefaultConfiguration.command = (onclick) => { this.createConfiguration(configuration.components); ...

Radio buttons with multiple levels

Looking to implement a unique two-level radio button feature for a specific option only. Currently, I have written a logic that will display additional radio buttons under the 'Spring' option. However, the issue is that when it's selected, t ...

What sets apart .to and .toService in InversifyJS?

I find the documentation on using .toService(MyClass) for transitive bindings confusing. The examples provided also show that achieving the same result is possible with a regular .to(MyClass). https://github.com/inversify/InversifyJS/blob/master/wiki/tran ...

What is the reason that the protected keyword is not retained for abstract properties in TypeScript?

I'm uncertain whether this issue in TypeScript is a bug or intended functionality. In my Angular project, I have 3 classes - an abstract service, a service that implements the abstract service, and a component that utilizes the implementing service. ...

Use TypeScript to cast the retrieved object from the local storage

const [savedHistory, setSavedHistory] = useState(localStorage.getItem('history') || {}); I'm facing an issue in TypeScript where it doesn't recognize the type of 'history' once I fetch it from localStorage. How can I reassign ...

Invoke cloud functions independently of waiting for a response

Attempting a clever workaround with cloud functions, but struggling to pinpoint the problem. Currently utilizing now.sh for hosting serverless functions and aiming to invoke one function from another. Let's assume there are two functions defined, fet ...

Can you explain the distinction, if one exists, between a field value and a property within the context of TypeScript and Angular?

For this example, I am exploring two scenarios of a service that exposes an observable named test$. One case utilizes a getter to access the observable, while the other makes it available as a public field. Do these approaches have any practical distincti ...