我在应用程序中使用打字稿,但发现react-redux出现了一些问题。 “连接”方法报告了一个问题,由于我是打字稿和Redux的新秀,所以我对此一无所知。我应该怎么做或应该在代码中的什么地方进行修改?非常感谢
使用typescript@3.3
,react@16.8.5
,react-redux@7.1.0
构建的应用程序。
// article
interface IArticle {
title: string,
author: string
}
// state
interface MyState {
list: [],
article: IArticle
}
// stateMapToProps
interface MyStateProps {
article: IArticle
}
// router match
interface MatchParams {
id: string
}
// own props
interface MyOwnProps extends RouteComponentProps < MatchParams > {
article: IArticle,
dispatch: (o: object) => {}
}
class ArticleContainer extends Component < MyOwnProps, {} > {
constructor(props: MyOwnProps) {
super(props);
}
componentDidMount() {
const {
dispatch
} = this.props;
const id = this.props.match.params.id
dispatch(fetchArticle(id))
}
render() {
const {
article
} = this.props;
return ( <
Article article = {
article
} > < /Article>
)
}
}
const mapStateToProps = (state: MyState): MyStateProps => {
return {
article: state.article
}
}
export default connect < MyStateProps, {}, {
article: IArticle
} > (
mapStateToProps
)(ArticleContainer)
这是异步操作fetchArticle
function fetchArticle(id: string) {
return function(dispatch: (action: AnyAction) => {}): Promise<void> {
dispatch(getArticle(id))
return axios.get(`/article/${id}`)
.then(res => {
dispatch(getArticleSuccess(res.data))
})
}
}
错误发生在export
行,并且消息如下:
类型'(state:MyState)=> MyStateProps'的参数不可分配 参数类型为“ MapStateToPropsParam”。类型'(state:MyState)=> MyStateProps'不是 可分配给“ MapStateToPropsFactory”类型。 参数“状态”和“初始状态”的类型不兼容。 类型“ {}”缺少类型“ MyState”中的以下属性:list,articlets(2345)
答案 0 :(得分:1)
最少的步骤即可编译代码:
MyOwnProps
应该
import { AnyAction } from 'redux';
interface AppThunkAction<TAction> {
(dispatch: (action: TAction) => void, getState: () => MyState): any;
}
// As you're going to dispatch thunk actions, dispatch should be overloaded
interface Dispatch<TAction> {
(action: AppThunkAction<TAction>): any
(action: TAction): TAction
}
// own props
interface MyOwnProps extends RouteComponentProps<MatchParams> {
article: IArticle,
dispatch: Dispatch<AnyAction>
}
如果要提供connect
函数的类型,请像这样添加MyState
作为最后一个类型
export default connect <MyStateProps, {}, {
article: IArticle
}, MyState >(
mapStateToProps
)(ArticleContainer)
或者您可以允许编译器自己推断类型,这是首选
export default connect(
mapStateToProps
)(ArticleContainer)
工作结果如此
import { Component } from 'react';
import { RouteComponentProps } from 'react-router-dom';
import { connect, ResolveThunks } from 'react-redux';
import { AnyAction } from 'redux';
import axios from 'axios';
// article
interface IArticle {
title: string,
author: string
}
// state
interface MyState {
list: [],
article: IArticle
}
// stateMapToProps
interface MyStateProps {
article: IArticle
}
// router match
interface MatchParams {
id: string
}
export interface AppThunkAction<TAction> {
(dispatch: (action: TAction) => void, getState: () => MyState): any;
}
interface Dispatch<TAction> {
(action: AppThunkAction<TAction>): any
(action: TAction): TAction
}
// own props
interface MyOwnProps extends RouteComponentProps<MatchParams> {
article: IArticle,
dispatch: Dispatch<AnyAction>
}
function getArticle(id: string) {
return {
type: 'GET_ARTICLE',
id
}
}
function getArticleSuccess(i: any) {
return {
type: 'SET_ARTICLE',
i
}
}
const fetchArticle = (id: string): AppThunkAction<AnyAction> =>
(dispatch, getState) => {
dispatch(getArticle(id))
return axios.get(`/article/${id}`)
.then(res => {
dispatch(getArticleSuccess(res.data))
})
}
class ArticleContainer extends Component<MyOwnProps, {}> {
constructor(props: MyOwnProps) {
super(props);
}
componentDidMount() {
const {
dispatch
} = this.props;
const id = this.props.match.params.id
dispatch(fetchArticle(id))
}
render() {
const {
article
} = this.props;
return (<div>article: {article}</div>
)
}
}
const mapStateToProps = (state: MyState): MyStateProps => {
return {
article: state.article
}
}
export default connect(
mapStateToProps
)(ArticleContainer)
答案 1 :(得分:0)
这是一个有效的示例,根据您的示例,如何在使用redux时键入反应文件。
// article-container.js file
import { connect, DispatchProp } from "react-redux";
import { Component } from "react";
// import the real RouteComponent, this is just a demo example
interface RouteComponentProps<T> {
match: { params: T };
}
// article
interface IArticle {
title: string;
author: string;
}
// import the real Article, this is just a demo example
const Article = ({ article }: { article: IArticle }) => {
return <div>{article.title}</div>;
};
// import the real fetchArticle, this is just a demo example
const fetchArticle = (id: string) => {
return {
type: "SOME_ACTION",
payload: {
id,
},
};
};
// state
interface MyState {
list: [];
article: IArticle;
}
// stateMapToProps
interface MyStateProps {
article: IArticle;
}
// router match
interface MatchParams {
id: string;
}
// own props
interface MyOwnProps {
article: IArticle;
}
type AllProps = MyOwnProps & RouteComponentProps<MatchParams> & DispatchProp;
class ArticleContainer extends Component<AllProps> {
constructor(props: AllProps) {
super(props);
}
componentDidMount() {
const { dispatch } = this.props;
const id = this.props.match.params.id;
dispatch(fetchArticle(id));
}
render() {
const { article } = this.props;
return <Article article={article} />;
}
}
const mapStateToProps = (state: MyState): MyStateProps => {
return {
article: state.article,
};
};
export default connect(
mapStateToProps
)(ArticleContainer);
并像这样使用它
import ArticleContainer from "./article-container";
export default () => {
// this is coming from router, just an example for demonstration
const match = { params: { id: "23" } };
return (
<div>
<ArticleContainer match={match} />
</div>
);
};
答案 2 :(得分:0)
最后解决了删除create table #T(Id int, Dept varchar(10),Amount int)
insert into #T
values(1,'Accounting',10000),(2,'Catering',5000),(3,'Cleaning',5000)
declare @Totll float = (Select sum(Amount) from #T)
Select *
from #T
union
select Id,Convert(varchar(50), (Amount/@Totll)*100)+'%',0
from #T
order by Id,Amount desc
方法的泛型声明,并将connect
与异步操作创建者一起使用的问题。代码如下。
ThunkDispatch
感谢您的帮助!