来自JavascriptServices网站的此模式和以下模式的新手,其中使用了带有React / Redux的Typescript。
我的是React Redux项目。
我有一个菜单tsx文件,显示一个菜单,该菜单与JavascriptServices中名为“NavMenu.tsx”的样板产品基本上没有改变
我想使用几个状态变量“IsAuthorised”& “用户名”。它们处于redux状态,我想只使用它们而不是设置它们等。
我在底部的connect语句中收到以下错误,特别是(NavMenu)是红色的,并且不知道如何修复此错误?
[TS] “typeof NavMenu”类型的参数不能分配给“Component&”类型的参数。 LoginState>”。 类型'typeof NavMenu'不能分配给'StatelessComponent& LoginState>”。 类型'typeof NavMenu'不提供签名'(props:DispatchProp& LoginState& {children?:ReactNode;},context?:any):ReactElement'。
以下是NavMenu类的代码 - 错误位于最后一行:
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;
修改
我注意到第一条评论,但需要有人对其进行扩展。
我在JavascriptServices示例中关注的文件如下所示。我已经遵循了他们的连接语法..在那个例子中没有提到mapStateToProps ......
这是:
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;
答案 0 :(得分:2)
假人是对的。根据Redux文档:
[mapStateToProps(state,[ownProps]):stateProps](Function):如果指定了此参数,则新组件将订阅Redux存储更新。这意味着每次更新商店时,都会调用mapStateToProps。 mapStateToProps的结果必须是普通对象,它将合并到组件的props中。如果您不想订阅商店更新,请传递null或undefined代替mapStateToProps。
在mapStateToProps
内,您要将Redux商店的部分映射到您需要定义的本地prop
。大多数mapStateToProps
来电都是这样的:
const mapStateToProps = (state) => {
return {
login: state.login
};
};
现在prop
login
已映射到Redux商店中的login
值。我对上述代码同样感到困惑,因为state.weatherForecasts
未分配给任何prop
,因此无法访问。我看到他们使用名为forecasts
的道具但是从interface
定义是否无法判断prop
是从父母传来还是应该属于他们的store
。我会坚持使用mapStateToProps
以上述方式 - 它在社区中非常标准,并且与TS一致。