GreenAsJade
GreenAsJade

Reputation: 14685

How do I do something like redux's `connect()` - put props onto a component at declaration time?

When I do this:

function mapStateToProps(state, props) {
    return {
        contacts: buildClientContacts(state)
    }
 }

export default connect(mapStateToProps)(Contacts)

I end up exporting a component like Contacts, except connect has put the contacts prop onto it for me (and used redux's state to build the contacts prop).

How can I do the same thing - declare a component based on another one, by adding props to it?

The reason I want to do this is that I want to put some props onto the component that have nothing to do with redux, instead of the mapToState shown in the code.

Something like this:

export default <Contacts mydata={somedata: data}>

(Obviously I can't put jsx there, but this is the sort of effect I want)

I could do this:

function mapStateToProps() {
    return {
        mydata: {somedata: data}
    }
 }

export default connect(mapStateToProps)(Contacts)

... but that's really abusing redux :)

Upvotes: 2

Views: 167

Answers (1)

Bartek Fryzowicz
Bartek Fryzowicz

Reputation: 6674

I think that what you need is a Higher-Order Component (HOC). Please read more about this pattern here. According to React docs:

... a higher-order component is a function that takes a component and returns a new component.

const EnhancedComponent = higherOrderComponent(WrappedComponent);

Whereas a component transforms props into UI, a higher-order component transforms a component into another component.

Actually redux connect also returns HOC.

So you can create an HOC that will set required data as property on the Contacts component. In your case it would look like this:

function contactsWithData(WrappedComponent, data) {
  return class extends React.Component {
    render() {
      return <WrappedComponent mydata={data} {...this.props}/>
    }
  }
}
...
export default contactsWithData(Contacts, {somedata: true});

Upvotes: 3

Related Questions