javascript - Programmatically focus on a form element after mounting -
i have form component (formcomponent) need programmatically focus on when sibling button component clicked. used able call this.refs.myform.focus()
(given myform
formcomponent) written call .focus()
on first form field inside. however, i've refactored , abstracted behavior higher order component wraps formcomponent now, .focus()
method on formcomponent intercepted wrapper component.
using react 0.14.x (so don't need reactdom.finddomnode()
dom components):
// formcomponent class formcomponentbase extends react.component { focus() { this.refs.firstfield.focus(); } render() { return ( <form ...> <input ref="firstfield" /> </form> ); } } // wraps formcomponent in wrapper component abstracted/reusable functionality const formcomponent = hocwrapper(formcomponent); // othercomponent class othercomponent extends react.component { handleclick(ev) { // error doesn't work because hocwrapper component intercepting .focus() call this.refs.myform.focus(); } render() { return ( <div> <button onclick={this.handleclick.bind(this)}>focus</button> <formcomponent ref="myform" /> </div> ); } }
passing focus
prop , managing state of whether form's first element focused in othercomponent
seems ludicrous. know can create get
/set
properties using defineproperty
(or that) accessing instance property calls method under hood generate result, js have ruby's missingmethod
or php's __call
can define catch-all method on hocwrapper
passes method calls through wrapped component? i've run issue before calling other methods through hoc wrapper components think defined pass-thru method of same name on hoc wrapper (which i'm wrong way).
rather passing focus state down, can pass ref ref callback function. here's fiddle illustrating
class formcomponentbase extends react.component { render() { return ( <form ...> <input ref={node => this.props.passnode(node)} /> </form> ); } } class othercomponent extends react.component { receivenode(node) { if (!this.state.node) this.setstate({ node }) } render() { return ( <div> <button onclick={() => this.state.node.focus()}>focus</button> <formcomponent passnode={this.receivenode} /> </div> ); } }
update: more idiomatic way doesn't pass node up. updated fiddle
var formcomponentbase = react.createclass({ render() { return <input ref={ node => node && this.props.shouldfocus && node.focus() }/> } }) var othercomponent = react.createclass({ getinitialstate() { return { shouldfocus: false } }, togglefocus(node) { // toggle demonstration this.setstate({ shouldfocus: !this.state.shouldfocus }) }, render: function() { return ( <div> <button onclick={() => this.togglefocus() }>focus</button> <child shouldfocus={this.state.shouldfocus} /> </div> ) } });
Comments
Post a Comment