Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 挂载后以编程方式关注表单元素_Javascript_Reactjs - Fatal编程技术网

Javascript 挂载后以编程方式关注表单元素

Javascript 挂载后以编程方式关注表单元素,javascript,reactjs,Javascript,Reactjs,我有一个表单组件(FormComponent),当单击同级按钮组件时,我需要以编程方式关注它。我曾经能够调用this.refs.myForm.focus(),它(给定myForm作为FormComponent)被编写为在内部的第一个表单字段上调用.focus()。但是,我已经将一些行为重构并抽象为一个更高阶的组件来包装FormComponent,所以现在,FormComponent上的.focus()方法被包装器组件截取 使用React 0.14.x(因此我不需要ReactDOM.findDOM

我有一个表单组件(FormComponent),当单击同级按钮组件时,我需要以编程方式关注它。我曾经能够调用
this.refs.myForm.focus()
,它(给定
myForm
作为FormComponent)被编写为在内部的第一个表单字段上调用
.focus()
。但是,我已经将一些行为重构并抽象为一个更高阶的组件来包装FormComponent,所以现在,FormComponent上的
.focus()
方法被包装器组件截取

使用React 0.14.x(因此我不需要
ReactDOM.findDOMnode()
用于DOM组件):

//FormComponent
类FormComponentBase扩展了React.Component{
焦点(){
this.refs.firstField.focus();
}
render(){
返回(
);
}
}
//将FormComponent包装在具有抽象/可重用功能的包装器组件中
const FormComponent=hocWrapper(FormComponent);
//其他组件
类OtherComponent扩展React.Component{
把手舔(ev){
//错误这不起作用,因为hocWrapper组件正在拦截.focus()调用
this.refs.myForm.focus();
}
render(){
返回(
集中
);
}
}

传递一个
focus
prop并管理表单的第一个元素是否集中在
OtherComponent
中的状态似乎很可笑。我知道您可以使用
defineProperty
(或类似的东西)创建
get
/
set
属性,其中访问实例属性调用引擎盖下的方法来生成结果,但是JS是否有Ruby的
missingMethod
或PHP的
\uu调用
之类的东西,我可以在我的
hocWrapper
上定义一个catch-all方法,它只将方法调用传递给包装好的组件?我以前在通过HOC包装器组件调用其他方法时遇到过这个问题,但我想我只是在HOC包装器上定义了一个同名的pass-thru方法(我很确定这是错误的方法)。

使用ref回调函数可以相当容易地向上传递ref,而不是向下传递焦点状态

类FormComponentBase扩展了React.Component{
render(){
返回(
this.props.passNode(node)}/>
);
}
}
类OtherComponent扩展React.Component{
接收节点(节点){
如果(!this.state.node)this.setState({node})
}
render(){
返回(
this.state.node.focus()}>focus
);
}
}    
更新:一种更为惯用的方式,它不会将节点传递给上

var FormComponentBase=React.createClass({
render(){
返回
node&&this.props.shouldFocus&&node.focus()
}/>
}
})
var OtherComponent=React.createClass({
getInitialState(){
返回{shouldFocus:false}
},
切换焦点(节点){
//切换以进行演示
this.setState({shouldFocus:!this.state.shouldFocus})
},
render:function(){
返回(
this.toggleFocus()}>focus
)
}
});

这里的
自动对焦是否足够?否<代码>自动对焦
用于页面最初加载时。我需要在初始页面加载后的任何时候以编程方式关注一个字段。实际上,在上一次迭代中,我在同一个组件上使用了类似的东西,但它看起来像一个React反模式,因为所有内容都应该沿着呈现树向下流动。我的看法错了吗?我不认为这违背了反应的美德。许多组件以循环方式一起工作,传递回调函数并将参数发送回父级。最可靠的方法是从parent/redux传递焦点值,但是如果有很多元素,那么可能会变得非常冗长,因此可能不值得这样做。或者,执行类似于
this.props.shouldFocus&&node.focus()}/>的操作。实际上,这似乎是一种非常简单的方法,您不必传递任何备份。对于您的
shouldFocus
示例,这意味着我需要跟踪
OtherComponent
中的状态,它将
shoulldfocus
设置为
true
,然后在字段模糊时将其设置为
false
。对我来说,这听起来像是疯狂的恶性循环。在我的应用程序的某些地方,跟踪情态动词的打开状态已经很有趣了。这个按钮不会切换焦点。它只是在单击时设置焦点,就这样。因此,您最初的解决方案可以更好地解决问题。如果你把它还原,我会把它标记为答案。
// FormComponent
class FormComponentBase extends React.Component {
    focus() {
        this.refs.firstField.focus();
    }

    render() {
        return (
            <form ...>
                <input ref="firstField" />
            </form>
        );
     }
}

// Wraps FormComponent in a wrapper component with abstracted/reusable functionality
const FormComponent = hocWrapper(FormComponent);

// OtherComponent
class OtherComponent extends React.Component {
    handleClick(ev) {
        // ERROR This doesn't work because the hocWrapper component is intercepting the .focus() call
        this.refs.myForm.focus();
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick.bind(this)}>Focus</button>
                <FormComponent ref="myForm" />
            </div>
        );
     }
}
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>
    );
  }
}    
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 for demonstration
    this.setState({ shouldFocus: !this.state.shouldFocus })
  },

  render: function() {
    return (
      <div>
        <button onClick={() => this.toggleFocus() }>focus</button>
        <Child shouldFocus={this.state.shouldFocus} />
      </div>
    )
  }
});