简体   繁体   English

React / Redux-通过单击组件2中的按钮来聚焦组件1的输入字段

[英]React / Redux - focus input field of Component 1 by click on button in Component 2

I asked a question on here earlier, but I think I should have been more specific. 我刚才在这里问了一个问题,但我想我应该更具体一些。 Say I have two components, which I call from a higher order component: 假设我有两个组件,我从一个更高阶的组件中调用它们:

So my higher order component, containing these components, looks like this (or at least its render method): 因此,包含这些组件的我的高阶组件看起来像这样(或至少是其render方法):

<div>
  <Navigation />
  <View />
</div>

Now, Navigation /> contains a button. 现在, Navigation />包含一个按钮。 Whenever that button is clicked, I want to set the focus on an input field, which is in <View /> . 每当单击该按钮时,我都希望将焦点设置在<View />的输入字段上。

If both things were in the very same component, I learned that I would do something like this: 如果两者都在同一个组件中,我就会知道我会做这样的事情:

<button onClick={() => {this.myInp.focus()}}>Focus Input</button>
<input type="text" ref={(ip) => this.myInp = ip} />

I am using Redux by the way, if this should make a difference. 顺便说一句,如果这应该有所作为,我正在使用Redux。

Since they are descendants of the same element you can use a state element and function to change that state element in the parent div and pass down as props to View and Navigation . 由于它们是同一元素的后代,因此您可以使用state元素和函数来更改父div中的state元素,并将其作为props传递给ViewNavigation

constructor(){

   super()

   this.state = {
    inputFocus:false;
   }

   this.setInputFocus = this.setInputFocus.bind(this)

}

setInputFocus(value){
   this.setState({inputFocus:false});
}

Then in the render method of the div just pass them down as props 然后在div的render方法中将它们作为props传递

<div>
  <Navigation setInputFocus={this.setInputFocus}/>
  <View inputFocus={this.state.inputFocus}/>
</div>

In the Navigation Navigation

<button onClick={() => {this.props.setInputFocus(true)}}>Focus Input</button>

and in the View 并在View

<input type="text"  ref={(ip) => this.myInp = ip}/>

and have this in the componentWillReceiveProps which detects when props change and runs actions then. 并将其包含在componentWillReceiveProps ,该componentWillReceiveProps将检测props何时更改并随后执行操作。

componentWillReceiveProps(nextProps){

    if(nextProps.inputFocus)
        this.myInp.focus()

}

So when the inputFocus changes in the parent it will fire the componentWillReceiveProps in the View element and focus the input . 因此,当父对象中的inputFocus发生更改时,它将触发View元素中的componentWillReceivePropsfocus input

Along with the refs, this problems also involves child to parent and parent to child interaction. 除裁判外,这个问题还涉及孩子与父母之间以及父母与孩子之间的互动。

So what I am doing in the below snippet is form the Navigation component, I have to call the parent component since a component can't directly have access to its siblings. 因此,我在以下代码段中所做的是从Navigation组件构成的,我必须调用父组件,因为一个组件无法直接访问其同级组件。 From the parent you can get access to the child component through refs and in turn you can also access the refs which are defined in the child component 从父级,您可以通过引用访问子级组件,然后您还可以访问在子级组件中定义的引用

See the snippet below 请参见下面的代码段

 class App extends React.Component { focusInput = () => { this.myView.myInput.focus() } render() { return ( <div> <Navigation focusInput={this.focusInput}/> <View ref={(view) => {this.myView = view}}/> </div> ) } } class Navigation extends React.Component { render() { return ( <button onClick={() => this.props.focusInput()}>Focus</button> ) } } class View extends React.Component { render() { return ( <input type="text" ref={(ip) => this.myInput = ip}/> ) } } ReactDOM.render(<App/>, document.getElementById('app')); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div> 

In case you have multiple buttons in navigation thorugh which you want to focus multiple different inputs, you can do so in the following manner 如果导航中有多个按钮要聚焦多个不同的输入,则可以按以下方式进行操作

 class App extends React.Component { focusInput = (ip) => { this.myView[ip].focus() } render() { return ( <div> <Navigation focusInput={(val) => this.focusInput(val)}/> <View ref={(view) => {this.myView = view}}/> </div> ) } } class Navigation extends React.Component { render() { return ( <div> <button onClick={() => this.props.focusInput("myInput1")}>Focus1</button> <button onClick={() => this.props.focusInput("myInput2")}>Focus2</button> </div> ) } } class View extends React.Component { render() { return ( <div> <input type="text" ref={(ip) => this.myInput1 = ip}/> <input type="text" ref={(ip) => this.myInput2 = ip}/> </div> ) } } ReactDOM.render(<App/>, document.getElementById('app')); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM