11

I am a trying to make a component which gets passed to react-redux's connect function. The component is as follows:

interface ITestProps {
  id: number
}

class TestComponent extends React.Component<ITestProps, {}> {
  render() {
    return (<div>
      {this.props.name}
    </div>)
  }
}

mapStateToProps(state) {}
mapDispatchToProps(dispatch) {}

let ConnectedComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(TestComponent)

The above code seems to work find if i render ConnectedComponent like so

<ConnectedComponent></ConnectedComponent>

i.e without the id prop. Shouldn't it throw an error since the ConnectedComponent is simply the connected form of TestComponent and TestComponent should have props of the form ITestProps. Is this how it is supposed to behave or am I doing something wrong.

4
  • Not familiar with TypeScript, but why do you need a different name (ConnectedComponent)? Can you not just do something like export default connect(mapStateToProps, mapDispatchToProps)(TestComponent); and then < TestComponent ></TestComponent >? Commented Jul 7, 2016 at 11:06
  • 1
    That is how I do.. I just thought this way it would be easier to understand Commented Jul 7, 2016 at 11:12
  • 1
    Hello, which definition types are you using for redux-react ? Commented Jul 7, 2016 at 11:40
  • The ones from DefinitelyTyped . This is my typings.json entry "react-redux": "registry:dt/react-redux#4.4.0+20160501125835" Commented Jul 7, 2016 at 13:01

3 Answers 3

20

I'm not sure why the typings can't infer the type from the presentational component alone, but it will work if ownProps is typed in connect ->

let ConnectedComponent = connect<{}, {}, ITestProps>(
  mapStateToProps,
  mapDispatchToProps
)(TestComponent)

It also can infer it if ownProps is typed in mapDispatchToProps ->

mapStateToProps(state, ownProps: ITestProps) {}
Sign up to request clarification or add additional context in comments.

2 Comments

by adding second argument to mapStateToProps (state) vs (state, ownProps) you're removing a lot of optimizations from connect! yes, react-redux does detect how many arguments you used in your function (mapStateToProps.length) and applies different optimization strategy.
Can you elaborate on what sort of optimizations get removed?
1

Include a constructor inside the class like this:

constructor(props) {
  super(props)
}

Without the constructor the props don't get loaded

Instead of

let ConnectedComponent = connect(
  mapStateToProps,
  mapDispatchToProps
)(TestComponent)

I added (obviously mapStateToProps & mapDispatchToProps have to be defined before the connect function)

@connect(mapStateToProps, mapDispatchToProps)

above

class TestComponent extends React.Component<ITestProps, {}> {

Comments

0

This is the correct behaviour. connect() will return a new container component that wraps your TestComponent as a child.

Here's part of the source code

class Connect extends Component {
...
    render() {
        const selector = this.selector
        selector.shouldComponentUpdate = false

        if (selector.error) {
          throw selector.error
        } else {
          return createElement(WrappedComponent, 
              this.addExtraProps(selector.props))
        }
    }
...
}

But you can specify the interface of the container's props as said by Radio- (and also the interfaces of StateProps and DispatchProps). You can see from the type definition that accepts TStateProps, TDispatchProps and TOwnProps, and will return ComponentDecorator

export declare function connect<TStateProps, TDispatchProps, TOwnProps>(
    mapStateToProps?: MapStateToProps<TStateProps, TOwnProps> | MapStateToPropsFactory<TStateProps, TOwnProps>,
    mapDispatchToProps?: MapDispatchToProps<TDispatchProps, TOwnProps> | MapDispatchToPropsFactory<TDispatchProps, TOwnProps>,
    mergeProps?: MergeProps<TStateProps, TDispatchProps, TOwnProps>,
    options?: Options
): ComponentDecorator<TStateProps & TDispatchProps, TOwnProps>;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.