Я использую машинописный текст в приложении, но обнаружил проблему с реакцией-редукцией. Метод «подключиться» сообщает о проблеме, и я понятия не имею об этом, так как я новичок с машинописным текстом и редуксом. Что мне делать или где в моем коде нужно изменить? Большое спасибо
Приложение, созданное с помощью [email protected], [email protected], [email protected].
// 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, и сообщение выглядит следующим образом:
Argument of type '(state: MyState) => MyStateProps' is not assignable to parameter of type 'MapStateToPropsParam'. Type '(state: MyState) => MyStateProps' is not assignable to type 'MapStateToPropsFactory'. Types of parameters 'state' and 'initialState' are incompatible. Type '{}' is missing the following properties from type 'MyState': list, articlets(2345)
также ваш компонент должен быть Component<MyOwnProps, MyState>
рекомендуем проверить следующие ресурс
@eenagy сначала спасибо. Я попробовал, и вместо этого часть ArticleContainer в строке export сообщает о сообщении, а также interface MyState представляет собой структуру хранилища, созданного с помощью избыточности, а не «состояние» Class, поэтому я думаю, что нет необходимости помещать его в дженерики. Надеюсь, я выражаюсь понятно.
И сообщение об ошибке для ArticleContainer в части connect выглядит следующим образом (запишите только первое предложение, так как оно слишком длинное, чтобы писать здесь): Аргумент типа 'typeof ArticleContainer' не может быть назначен параметру типа 'ComponentType<Matching<MyStateProps & DispatchProp <AnyAction>, MyOwnProps>>'......ts(2345)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вот рабочий пример того, как ввести файл реакции при использовании избыточности на основе вашего примера.
// 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>
);
};
Спасибо за вашу помощь, я решил проблему, основанную на этом.
Минимальные шаги для компиляции кода:
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)
Спасибо за вашу помощь. Этот метод решает упомянутую мной ошибку, однако dispatch(fetchArticle(id)) сообщает об ошибке, потому что мой fetchArticle метод является асинхронным и возвращает обещание? ps: дополняю код fetchArticle в вопросе.
Я думаю, что ошибка в основном сообщает о типе параметра, но я понятия не имею, как ее решить. Вот сообщение об ошибке: Аргумент типа '(dispatch: (action: AnyAction) => {}) => Promise<void>' не может быть назначен параметру типа 'AnyAction'. Свойство 'type' отсутствует в типе '(dispatch: (action: AnyAction) => {}) => Promise<void>', но требуется в типе 'AnyAction'.ts(2345)
Я уже решил проблему на основе вашего метода, большое спасибо за вашу помощь!
Извините, не упоминает об этом. Я обновил ответ и набрал dispatch, чтобы он мог принимать функции в качестве аргументов.
Наконец, решено с удалением объявления дженериков метода connect и использованием ThunkDispatch с создателем асинхронного действия. Код ниже.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { ThunkDispatch } from 'redux-thunk';
import { fetchArticle } from '../store/actions';
import { RouteComponentProps } from 'react-router-dom';
import Article from '../components/Article/Article'
import { AnyAction } from 'redux';
// article
interface IArticle {
title: string,
author: string
}
// state
interface MyState {
list: [],
article: IArticle
}
// stateMapToProps
interface StateToProps {
article: IArticle
}
// router match
interface MatchParams {
id: string
}
// own props
interface MyOwnProps extends RouteComponentProps<MatchParams> {
article: IArticle,
getArticle: (id: string) => Promise<void>
}
class ArticleContainer extends Component<MyOwnProps, {}> {
constructor(props: MyOwnProps) {
super(props);
}
componentDidMount() {
const { getArticle } = this.props;
const id = this.props.match.params.id
getArticle(id)
}
render() {
const { article } = this.props;
return (
<Article article = {article}></Article>
)
}
}
const mapStateToProps = (state: MyState): StateToProps => {
return {
article: state.article
}
}
const mapDispatchToProps = (dispatch: ThunkDispatch<any, any, AnyAction>) => {
return {
getArticle: (id: string) => dispatch(fetchArticle(id))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ArticleContainer)
Спасибо за помощь!
Просто удалите ввод из подключения. Connect уже делает вывод из mapStateToProps.
export default connect(mapStateToProps)(ArticleContainer);