Norayr Ghukasyan
Norayr Ghukasyan

Reputation: 1418

Can't handle typescript with react and redux

I am new at typescript and really struggling. I can't understand where to begin and where to end . Yes , there are many recourses on internet , but i couldn't manage to get that information and use in my project . Hope to meet some help here. I have also done some typechecking and if you find something that i could have done better , please just tell me to improve it. So now i am struggling with redux mapStateToProps and mapDispatchToProps . I have tried many variants , but every time i have got some kind of errors. I will post my code which represents my dashboard component which is connected to state .

import * as React from 'react';
import { connect } from 'react-redux';
import SearchIcon from '../SvgIcons';
import MapComponent from '../Map';
import { getEventInfo, getUserInfo } from '../../actions';

interface StateProps {
  userReducer: {
    accessToken: string
  },
  eventReducer: {
    events: object[]
  }
}

interface DispatchProps {
  dispatchUserInfo: () => void;
  dispatchEventInfo: (accessToken: string, query: string) => void;
}

interface OwnProps {
  onSubmit: (e: React.FormEvent<HTMLFormElement>) => void,
  accessToken: string,
  events: object[]
}

type Props = StateProps & DispatchProps & OwnProps;

class DashboardPage extends React.Component<Props, {}> {              
  componentDidMount() {
    const { dispatchUserInfo } = this.props;
    dispatchUserInfo();
  }

  handleEventSearch = e => {
    e.preventDefault();
    const { dispatchEventInfo, accessToken } = this.props;
    const query: string = e.target.children[0].value;
    dispatchEventInfo(accessToken, query);
  }

  render() { 
    const { events } = this.props; 
    return (
      <div className="dashboard-container">
        <div className="search-event">
          <form className="search-event__form" onSubmit={this.handleEventSearch}>
            <input
              autoComplete="off"
              type="text"
              name="search-event"
              placeholder="Search an event"
              className="search-event__input"
              aria-label="Enter search text"
            />
            <button type="submit" className="search-event__button">
              <SearchIcon />
              Search
            </button>
          </form>
          <p className="sign-out">
            <a href="/api/logout" className="btn btn--sign-out sign-out__button">Sign out</a>
          </p>
        </div>
        <div className="google-map">
          <MapComponent events={events} />
        </div>
      </div>
    );
  }
}

const mapStateToProps = (state: StateProps) => {
  const accessToken = state.userReducer.accessToken || '';
  const events = state.eventReducer || [];
  return {
    accessToken,
    events
  };
};

const mapDispatchToProps = (dispatch: DispatchProps) => ({
  dispatchEventInfo(query: string, token: string) {
    dispatch(getEventInfo(query, token));
  },
  dispatchUserInfo() {
    dispatch(getUserInfo());
  }
});

export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage);

These are typescript errors 1) Refers tohandleEventSearch`method

[ts] Parameter 'e' implicitly has an 'any' type.

2) refers to mapDispatchToProps

[ts] Cannot invoke an expression whose type lacks a call signature. Type 'DispatchProps' has no compatible call signatures.

3) refers to mapDispatchToProps in connect HOC

Argument of type '(dispatch: DispatchProps) => { dispatchEventInfo(query: string, token: string): void; dispatchUserInfo(): void; }' is not assignable to parameter of type 'MapDispatchToPropsParam<{ dispatchEventInfo(query: string, token: string): void; dispatchUserInfo(): void; }, {}>'.

Type '(dispatch: DispatchProps) => { dispatchEventInfo(query: string, token: string): void; dispatchUserInfo(): void; }' is not assignable to type 'MapDispatchToPropsFunction<{ dispatchEventInfo(query: string, token: string): void; dispatchUserInfo(): void; }, {}>'.

Types of parameters 'dispatch' and 'dispatch' are incompatible. Type 'Dispatch>' is not assignable to type 'DispatchProps'. Property 'dispatchUserInfo' is missing in type 'Dispatch>'.

Also if you can provide me very good sources to learn about react and redux with typescript , so i could easily write my code.

Upvotes: 1

Views: 615

Answers (1)

Ebuall
Ebuall

Reputation: 1446

  1. You need to supply event type explicitly, any or React.SyntheticEvent<...something>

  2. Dispatch parameter should be Dispatch type from Redux

Also a little tip, you can define your props like:
ReturnType<typeof mapStateToProps> & ReturnType<typeof mapDispatchToProps> & OwnProps
and remove unnecessary interfaces

Upvotes: 1

Related Questions