Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use context to pass down redux and use decorators on smart components #245

Closed
cgarvis opened this issue Jul 10, 2015 · 5 comments
Closed

Comments

@cgarvis
Copy link

cgarvis commented Jul 10, 2015

Love the ideas with redux. I haven't been able to dig into the actually code, but the API was bothering me a little so I've been play with some ideas. Think context and ES7 Decorators make for a better interface. Here are some code snippets demonstrating it.

Smart component would look like:

import autobind from 'autobind-decorator'

@autobind
@Redux
export default class CounterApp extends React.Component {
  render() {
    return (
      ...
     )
  }

  decrement() {
    this.dispatchAction(CounterActions.decrement);
  }

  increment() {
    this.dispatchAction(CounterActions.decrement);
  }
}

Redux mixin would look like:

export function Redux(Component) {
  Component.contextTypes = {
    dispatch: React.PropTypes.func.isRequired
  }

  Component.prototype.dispatchAction = function(action) {
    this.context.dispatch(action)
  }

  return Component
}

Redux Component and loading CounterApp

import autobind from 'autobind-decorator'

@autobind
class Redux extends React.Component {
  constructor() {
    this.state = {}
  }

  getChildContext() {
    return {
      dispatch: this.dispatch
    }
  }

  dispatch(action) {
    ...
  }

  render() {
    return React.cloneElement(this.props.children, this.state);
  }
}

Redux.childContextTypes = {
  dispatch: React.PropTypes.func
}

// Only allow one element on children
Redux.propTypes = {
  children: React.PropTypes.element.isRequired
}

ReactDOM.render(<Redux><CounterApp /></Redux>, document.body);
@FAQinghere
Copy link

I agree that the API is a little awkward as is. Evaluating only the API itself, this looks fantastic.

@acdlite
Copy link
Collaborator

acdlite commented Jul 11, 2015

The current API is designed to encourage best React practices by forcing you to pass action creators down as props. Read Dan's article about "Smart and Dumb Components" https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0

Your CounterApp is a smart component. Following best practices, you should pass down this.decrement and this.increment as props to child dumb components so they can use them as event handlers. Once you've done that, you'll have written more lines of code that you would with the current API, which is optimized for the smart vs dumb component pattern.

@gaearon
Copy link
Contributor

gaearon commented Jul 11, 2015

I'm not too fond of the current <Provider> and <Connector> API.
If you have better ideas please chime in here: reduxjs/react-redux#1

@cgarvis
Copy link
Author

cgarvis commented Jul 12, 2015

@acdlite This is not meant to be a demo of "best practices", only a demo of a slightly different API for redux. My goals are to remove the need for Provider, Connector, and the "callback render". Which is accomplished by using context.

@acdlite
Copy link
Collaborator

acdlite commented Jul 12, 2015

@cgarvis If I'm not mistaken, you're proposing a new API to replace the current once. I'm telling you why this particular proposal isn't likely to be accepted :)

Let's move further discussion over to this thread reduxjs/react-redux#1

@acdlite acdlite closed this as completed Jul 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants