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

Access wrapped component's methods from a contrainer #267

Closed
elado opened this issue Jan 25, 2016 · 1 comment
Closed

Access wrapped component's methods from a contrainer #267

elado opened this issue Jan 25, 2016 · 1 comment

Comments

@elado
Copy link

elado commented Jan 25, 2016

A simple component may have public methods that are accessible if it's a ref somewhere. I usually use if for focus, scrollToBottom etc.

class ArticleSearch extends Component {
  render() { return  <div><input type="text" ref="input" /></div> }

  focus() { this.refs.input.focus() }
}

// some other component:

render() { return <div>...<ArticleSearch ref="articleSearch" />...</div> }

doSomething() {
  this.refs.articleSearch.focus()
}

In case component is @connected, the methods aren't accessible anymore.

I can use withRef: true and this.refs.articleSearch.getWrappedInstance().focus() but that wouldn't be clean, as I explicitly specify the getWrappedInstance(). If I remove the @connect code will break.

Would it make sense to copy some selective methods from wrapped component into the Connect component?

Something like (https://github.com/rackt/react-redux/blob/master/src%2Fcomponents%2Fconnect.js) :

function connect(mapStateToProps, mapDispatchToProps, mergeProps, options = {}) {
  // ...
  return function wrapWithConnect(WrappedComponent) {
    class Connect extends Component {
      // ...
      constructor(props, context) {
        //...

        if (options.copyMethods) {
          invariant(options.withRef, 'copyMethods requires the withRef option to be true')
          options.copyMethods.forEach(m => this[m] = (...args) { return this.wrappedInstance[m](...args) })
        }
      }

Usage:

@connect(null, null, null, { withRef: true, copyMethods: ['focus', 'scrollToBottom'])
class ArticleSearch extends Component {
  //...
  focus() { ... }
  scrollToBottom() { ... }
}

I'll make a PR if it seems fine.

Update

I see all static methods are copied with hoistStatics, but prototype methods are left out. Solution can be something similar that also copies all prototype methods and binds them to the ref.

@gaearon
Copy link
Contributor

gaearon commented Jan 26, 2016

As described in #270 (comment), it's best to pass callback refs as props for that rather than expose instance methods.

@gaearon gaearon closed this as completed Jan 26, 2016
foiseworth pushed a commit to foiseworth/react-redux that referenced this issue Jul 30, 2016
erikmueller pushed a commit to ePages-de/react-components that referenced this issue Oct 30, 2018
"it's best to pass callback refs as props for that rather than expose instance methods" - Dan
reduxjs/react-redux#267 (comment)
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

2 participants