2017-06-04 16 views
2

這裏我的目標是創建一個表單,當你點擊返回鍵並在最後一次輸入時提交表單時,該表單會將你選擇到下一個輸入元素。用反應改變文本輸入的焦點

這是爲移動設備構建的,因爲在瀏覽器中沒有使用「下一步」按鈕而不是「轉到鍵盤」按鈕的選項(關於此的更多信息,請參閱this answer)。

爲了更好地觀察這一點,這裏是一個畫面:enter image description here

我也寫了一些代碼,但這裏的關鍵是,我沒能趕上在正確的位置的情況下,這樣的形式得到在返回後立即提交或者當我阻止事件發生時,在我返回2次後焦點發生改變。

看到這裏的例子:https://codepen.io/ofhouse/pen/Rgwzxy(我也粘貼下面的代碼)

class TextInput extends React.Component { 
    constructor(props) { 
    super(props); 
    this._onKeyPress = this._onKeyPress.bind(this); 
    } 

    componentDidMount() { 
    if (this.props.focus) { 
     this.textInput.focus(); 
    } 
    } 

    componentDidUpdate(nextProps) { 
    if (nextProps.focus) { 
     this.textInput.focus(); 
    } 
    } 

    _onKeyPress(e) { 
    if (e.key === 'Enter') { 
     this.props.onSubmit(e); 
    } 
    } 

    render() { 
    return (
     <div> 
     <input 
      type="text" 
      onKeyPress={this._onKeyPress} 
      ref={input => { 
      this.textInput = input; 
      }} 
     /> 
     </div> 
    ); 
    } 
} 

class Application extends React.Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     currentElement: 0, 
    }; 
    } 

    _submitForm(e) { 
    // If I remove this preventDefault it works, but also the form is submitted --> SiteReload 
    e.preventDefault(); 
    } 

    _changeFocus(nextElement) { 
    return e => { 
     this.setState({ 
     currentElement: nextElement, 
     }); 
    }; 
    } 

    render() { 
    const { currentElement } = this.state; 
    return (
     <form> 

     <h1>React input focus</h1> 

     <TextInput focus={currentElement === 0} onSubmit={this._changeFocus(1)} /> 
     <TextInput focus={currentElement === 1} onSubmit={this._changeFocus(0)} /> 

     <div> 
      <button type="submit" onClick={this._submitForm}>Submit</button> 
     </div> 

     </form> 
    ); 
    } 
} 

ReactDOM.render(<Application />, document.getElementById('app')); 

回答

1

你用最好的方法,我不認爲,讓我解釋一下。輸入的聚焦由原生DOM元素的focus方法完成。要知道基於哪個輸入具有當前焦點的焦點輸入是必須在這些輸入的容器中執行的邏輯,即您的案例中的Application組件。

我做了你的代碼的一些顯著的變化,現在它的工作:CodePen

讓我來解釋一下:

首先,我們要防止keyPressed事件輸入的提交當按下鍵是'Enter',防止形式submit

_onKeyPress(e) { 
    if (e.key === 'Enter') { 
    this.props.onSubmit(e); 
    e.preventDefault(); 
    } 
} 

我們不需要任何componenDidMount也不componentDidUpdateTextInput所有我們需要的是一個focus方法:

focus() { 
    this.textInput.focus(); 
} 

大部分的變化在Application成分製成。首先,我們不需要狀態,我們真正需要的是將輸入放在一個數組中,以便我們可以在其上調用focus

constructor(props) { 
    super(props); 

    this.inputs = []; 
} 

要改變的重點,我們只需要輸入的索引來調用focus方法TextInput組件:

_changeFocus(index) { 
    return e => { 
    this.inputs[index].focus(); 
    }; 
} 

然後,我們需要一種方法來輸入添加到this.inputs中, ref屬性將是理想的,我已經創建方法_addInput爲這樣的幫手:

_addInput(index) { 
    return input => { 
    this.inputs[index] = input; 
    }; 
} 

最後,渲染TextInput■當你需要_addInput通過他們ref_changeFocusonSubmit,各自的指標:

<TextInput ref={this._addInput(0)} onSubmit={this._changeFocus(1)} /> 
<TextInput ref={this._addInput(1)} onSubmit={this._changeFocus(0)} /> 

在第二TextInput我將重點轉向第一個,但也許提交表單會更有用。

+0

哇,非常感謝你花時間詳細指出了一切!你的方法比我的更清潔,在這裏真正學到了一些東西。我已經在我的代碼上進行了測試,它運行得非常好,肯定爲我節省了幾個小時。謝謝! – ofhouse