简体   繁体   English

在另一个组件的输入之间切换焦点

[英]Toggle focus between inputs from another component

I have next code: 我有下一个代码:

<Wrapper>
   <InputsGroup />
   <Controls />
</Wrapper>

In InputsGroup component I have a list of inputs: 在InputsGroup组件中,我有一个输入列表:

// InputsGroup 
<>
   <input ... />
   <input ... />
   <input ... />
   ...
</>

In Controls component I have two buttons: Next and Previously. 在控件组件中,我有两个按钮:下一个和上一个。

// Controls

<>
   <button> Prev </button>
   <button> Next </button>
</>

The idea, is I need to toggle focus between inputs when click 'Next' or 'Prev' button. 这个想法是,当我单击“下一步”或“上一步”按钮时,需要在输入之间切换焦点。

What is the best way to do it, and how can I manage the focus of inputs? 最好的方法是什么?如何管理输入的焦点?

This is how it's looks like: 它是这样的:
在此处输入图片说明

I would use the local state to track the focused input field. 我将使用本地状态来跟踪重点输入字段。

In the outer componenent: 在外部组件中:

state = {
  focused: 'input_name' || defaultValue
};

handleFocusChange = focused => {
  // Use your own logic to change the focus
  this.setState({ focused });
};

render() {
  const { focused } = this.state;

  return (
    <Wrapper>
      <InputsGroup focused={focused} />
      <Controls onClick={this.handleFocusChange} />
    </Wrapper>
  );
}

Inside your InputsGroup component where you render your inputs: 在您的InputsGroup组件内部,您可以在其中渲染输入:

const { focused } = this.props;

<>
  {/* .... */}
  <input
    {/* ... */}
    autoFocus={focused === inputName}
  />
</>

At the end in your Controls component: 在控件组件的最后:

const { onClick } = this.props;
<>
 <button onClick={() => onClick(/* you need your own logic here, too */)}> Prev </button>
 <button onClick={() => onClick(/* you need your own logic here, too */)}> Next </button>
</>

Usually I keep my input field options in a separated constant file, therefore the logic can be super easy to implement. 通常,我将输入字段选项保存在单独的常量文件中,因此逻辑可以非常容易实现。 You can use this to walk through the inputs with button click or render the input fields. 您可以使用它来通过单击按钮浏览输入或渲染输入字段。

Example of a possible field map: 可能的字段图示例:

const fields = [
  { name: 'input_name_1', type: 'text', ... },
  { name: 'input_name_2', type: 'text', ... }
];

You can solve this using Refs concept, this is a working solution:- 您可以使用Refs概念解决此问题,这是一个可行的解决方案:-

 class App extends React.Component{ constructor(props) { super(props); this.state = { focus: 0 }; this.textInput0 = React.createRef(); this.textInput1 = React.createRef(); this.textInput2 = React.createRef(); } componentDidMount() { this.textInput0.current.focus(); } clickHandler = btnType => { let focus = this.state.focus; if (btnType === "prev") { if (focus !== 0) focus--; } else { if (focus !== 2) focus++; } this.focusInputField(focus); this.setState({ focus: focus }); }; focusInputField = id => { //console.log(id); switch (id) { case 0: this.textInput0.current.focus(); break; case 1: this.textInput1.current.focus(); break; case 2: this.textInput2.current.focus(); break; default: this.textInput0.current.focus(); } }; render() { return ( <React.Fragment> <input placeholder="textInput0" ref={this.textInput0} /> <br /> <input placeholder="textInput1" ref={this.textInput1} /> <br /> <input placeholder="textInput2" ref={this.textInput2} /> <br /> <button onClick={() => this.clickHandler("prev")}>Prev</button> <button style={{marginLeft: "20px"}} onClick={() => this.clickHandler("next")}>Next</button> </React.Fragment> ); } } ReactDOM.render(<App />, document.getElementById('root')) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id='root'></div> 

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

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