简体   繁体   中英

In a Typescript React project how do I instantiate a connected component?

This project is set up with distinct components that have very little relation to one another and should be displayed side-by-side. Thus, I want to set the application up so that each major component queries the Redux store separately. The only example in the documentation shows the state being passed into the top component and then broken out for each subcomponent.

This is a snapshot of the app at the time that I am running into my bug.

Put simply, I am getting this error when I try to instantiate a connected react component within an unconnected react component:

ERROR in /Users/savanni/src/dashboard/src/main.tsx
./src/main.tsx
[tsl] ERROR in /Users/savanni/src/dashboard/src/main.tsx(22,8)
      TS2741: Property 'predictions' is missing in type '{}' but required in type 'Readonly<Pick<Props, "predictions">>'.

A simplified version of my main component looks like this:

const AppMain = () => (
  <div className={csn(["flex", "full-width"])}>
    <TransitView />
    <WeatherView />
  </div>
)

I have TransitView set up like this:

interface Props {
  predictions: Array<mbta.RawPrediction>
}

export const Transit: React.SFC<Props> = ({ predictions }) => (
  <div>
    {predictions.map(prediction => (
      <Prediction key={prediction.id} prediction={prediction} />
    ))}
  </div>
)

export default connect((state: AppState) => {
  predictions: getPredictions(state)
})(Transit)

Finally, I'm instantiating my AppMain from within a <Provider> component.

However, I'm getting this type error on the <TransitView /> declaration.

The reason this stumps me is that I know from building previous applications (but in Javascript) that TransitView takes no components at all and that the redux Provider and connect will pass the state parameter in to the correct location.

So, how do I appease Typescript?

Are you importing the correct export?

You are default exporting the connected component, so it is the default export you should import.

eg you should import the default export

import TransitView from './transitView'

you should not import the named export

import { Transit } from './transitView'

The whole mess came down to a misleading error message.

While that error may have been correct, the relevant error was in this code:

export default connect((state: AppState) => {
  predictions: getPredictions(state),
})(Transit)

Note how in my parameter to connect, it is a function to a block, not a function to a dictionary. The correct code involves merely one extra set of parenthesis.

export default connect((state: AppState) => ({
  predictions: getPredictions(state),
}))(Transit)

Technically, this implies that I don't have a good type signature for connect . I can't actually understand the type signature for connect in @types/react-redux , so I can neither explore this further nor determine whether this is intended behavior.

I was able to discover the problem by changing the type signature of Transit temporarily to any so that the code would compile, and then interpreting the error messages that showed up in my runtime console.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM