Typescript + React / Redux: Властивість "XXX" не існує для типу 'IntrinsicAttributes & IntrinsicClassAttributes


91

Я працюю над проектом з Typescript, React та Redux (усі працюють в Electron), і я зіткнувся з проблемою, коли включаю один компонент на основі класу до іншого і намагаюся передавати параметри між ними. Вільно кажучи, у мене є така структура для компонента контейнера:

class ContainerComponent extends React.Component<any,any> {
  ..
  render() {
    const { propToPass } = this.props;
    ...
    <ChildComponent propToPass={propToPass} />
    ...
  }
}

....
export default connect(mapStateToProps, mapDispatchToProps)(ContainerComponent);

І дочірній компонент:

interface IChildComponentProps extends React.Props<any> {
  propToPass: any
}

class ChildComponent extends React.Component<IChildComponentProps, any> {
  ...
}

....
export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);

Очевидно, що я включаю лише основи, і в обох цих класах є набагато більше, але я все одно отримую помилку, коли намагаюся запустити те, що мені здається дійсним кодом. Точна помилка, яку я отримую:

TS2339: Property 'propToPass' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, ComponentState>> & Readonly<{ childr...'.

Коли я вперше зіткнувся з помилкою, я подумав, що це тому, що я не передав інтерфейс, що визначає мої реквізити, але я створив це (як ви можете бачити вище), і воно все ще не працює. Цікаво, чи чогось мені не вистачає?

Коли я виключаю опис ChildComponent з коду в ContainerComponent, він стає чудово (за винятком того, що мій ChildComponent не має критичного опису), але разом із ним у JSX Typescript відмовляється його компілювати. Я думаю, що це може мати щось спільне з обтіканням підключень, заснованим на цій статті , але проблеми в цій статті виникли у файлі index.tsx і були проблемами з провайдером, і я отримую свої проблеми в іншому місці.

Відповіді:


54

Отож, прочитавши деякі відповідні відповіді (зокрема цю та цю та подивившись відповідь @ basarat на запитання, мені вдалося знайти щось, що мені підходить. Схоже (на мої відносно нові очі React), як Connect не постачав явний інтерфейс до компонента контейнера, тому його спантеличила підтримка, яку він намагався передати.

Отже, компонент контейнера залишився незмінним, але дочірній компонент трохи змінився:

interface IChildComponentProps extends React.Props<any> {
  ... (other props needed by component)
}

interface PassedProps extends React.Props<any> {
  propToPass: any
}

class ChildComponent extends React.Component<IChildComponentProps & PassedProps, any> {
  ...
}

....
export default connect<{}, {}, PassedProps>(mapStateToProps, mapDispatchToProps)    (ChildComponent);

Вищевказане вдалося спрацювати на мене. Явна передача реквізиту, який компонент очікує від контейнера, здавалася, працює, і обидва компоненти відтворені належним чином.

ПРИМІТКА: Я знаю, що це дуже спрощена відповідь, і я не зовсім впевнений, ЧОМУ це працює, тому, якщо досвідченіший ніндзя React хоче залишити трохи знань щодо цієї відповіді, я був би радий внести зміни.


7
Але React.Propsбуло застаріле !!
Суніл Шарма


-1

Замість export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);, віддайте перевагу connectдекоратору https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/app/fileTree.tsx#L136-L146

@connect((state: StoreState): Props => {
    return {
        filePaths: state.filePaths,
        filePathsCompleted: state.filePathsCompleted,
        rootDir: state.rootDir,
        activeProjectFilePathTruthTable: state.activeProjectFilePathTruthTable,
        fileTreeShown: state.fileTreeShown,
    };
})

Де підключення визначено тут https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/typings/react-redux/react-redux.d.ts#L6-L36

Чому?

Здається, що визначення, які ви використовуєте, ймовірно застарілі або недійсні (можливо, написані погано).


2
Схоже, підключення дочірнього компонента, безумовно, було проблемою, але я знайшов спосіб вирішити проблему, не змінюючи типізацій, які я використовував. Використовуючи рішення за цим посиланням, мені вдалося змінити підключення на: connect<{}, {}, PassedProps> Where PassedProps - це реквізит, який компонент отримує з батьківського контейнера.
головний герой
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.