Novice at this and following patterns from JavascriptServices site which uses Typescript with React/Redux amoung others.
Mine is a React Redux project.
I have a menu tsx file that displays a menu that is largely unaltered from the boilerplate offering from JavascriptServices called "NavMenu.tsx"
I wanted to use a couple of state variables "IsAuthorised" & "username". These are in redux state and I want to just use them not set them etc.
I am getting the following error on the connect statement at the bottom and in particular (NavMenu) is red underscored and have no idea how to fix this error?
[ts] Argument of type 'typeof NavMenu' is not assignable to parameter of type 'Component & LoginState>'. Type 'typeof NavMenu' is not assignable to type 'StatelessComponent & LoginState>'. Type 'typeof NavMenu' provides no match for the signature '(props: DispatchProp & LoginState & { children?: ReactNode; }, context?: any): ReactElement'.
Here is the code for the NavMenu class - the error is on the very last line:
import * as React from "react";
import { NavLink, Link } from "react-router-dom";
import {
Navbar,
Nav,
NavItem,
NavDropdown,
MenuItem,
Glyphicon
} from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
import { connect } from "react-redux";
import { ApplicationState } from "../store";
import * as LoginState from "../store/Login";
// At runtime, Redux will merge together...
type NavMenuProps = LoginState.LoginState;
export class NavMenu extends React.Component<NavMenuProps, {}> {
public render() {
return (
<div className="main-nav">
<div className="navbar navbar-inverse">
<div className="navbar-header">
<button
type="button"
className="navbar-toggle"
data-toggle="collapse"
data-target=".navbar-collapse"
>
<span className="sr-only">Toggle navigation</span>
<span className="icon-bar" />
<span className="icon-bar" />
<span className="icon-bar" />
</button>
<Link className="navbar-brand" to={"/"}>
JobsLedger_API
</Link>
</div>
<div className="clearfix" />
<div className="navbar-collapse collapse">
<ul className="nav navbar-nav">
<li>
<NavLink exact to={"/"} activeClassName="active">
<span className="glyphicon glyphicon-home" /> Home
</NavLink>
</li>
<li>
<NavLink to={"/counter"} activeClassName="active">
<span className="glyphicon glyphicon-education" /> Counter
</NavLink>
</li>
<li>
<NavLink to={"/fetchdata"} activeClassName="active">
<span className="glyphicon glyphicon-th-list" /> Fetch data
</NavLink>
</li>
</ul>
</div>
</div>
</div>
);
}
}
export default connect(
(state: ApplicationState) => state.login // Selects which state properties are merged into the component's props
)(NavMenu) as typeof NavMenu;
EDIT
I note the 1st comment but need someone to expand on it.
The file I was following in the JavascriptServices example is below. I have followed their connect syntax.. there was no mention of mapStateToProps in that example...
Here it is:
import * as React from 'react';
import { Link, RouteComponentProps } from 'react-router-dom';
import { connect } from 'react-redux';
import { ApplicationState } from '../store';
import * as WeatherForecastsState from '../store/WeatherForecasts';
// At runtime, Redux will merge together...
type WeatherForecastProps =
WeatherForecastsState.WeatherForecastsState // ... state we've requested from the Redux store
& typeof WeatherForecastsState.actionCreators // ... plus action creators we've requested
& RouteComponentProps<{ startDateIndex: string }>; // ... plus incoming routing parameters
class FetchData extends React.Component<WeatherForecastProps, {}> {
componentWillMount() {
// This method runs when the component is first added to the page
let startDateIndex = parseInt(this.props.match.params.startDateIndex) || 0;
this.props.requestWeatherForecasts(startDateIndex);
}
componentWillReceiveProps(nextProps: WeatherForecastProps) {
// This method runs when incoming props (e.g., route params) change
let startDateIndex = parseInt(nextProps.match.params.startDateIndex) || 0;
this.props.requestWeatherForecasts(startDateIndex);
}
public render() {
return <div>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server and working with URL parameters.</p>
{ this.renderForecastsTable() }
{ this.renderPagination() }
</div>;
}
private renderForecastsTable() {
return <table className='table'>
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
{this.props.forecasts.map(forecast =>
<tr key={ forecast.dateFormatted }>
<td>{ forecast.dateFormatted }</td>
<td>{ forecast.temperatureC }</td>
<td>{ forecast.temperatureF }</td>
<td>{ forecast.summary }</td>
</tr>
)}
</tbody>
</table>;
}
private renderPagination() {
let prevStartDateIndex = (this.props.startDateIndex || 0) - 5;
let nextStartDateIndex = (this.props.startDateIndex || 0) + 5;
return <p className='clearfix text-center'>
<Link className='btn btn-default pull-left' to={ `/fetchdata/${ prevStartDateIndex }` }>Previous</Link>
<Link className='btn btn-default pull-right' to={ `/fetchdata/${ nextStartDateIndex }` }>Next</Link>
{ this.props.isLoading ? <span>Loading...</span> : [] }
</p>;
}
}
export default connect(
(state: ApplicationState) => state.weatherForecasts, // Selects which state properties are merged into the component's props
WeatherForecastsState.actionCreators // Selects which action creators are merged into the component's props
)(FetchData) as typeof FetchData;
mapStateToProps
function must return an object , aka{...}
– Meme Composer