javascript - react - 渲染後將焦點放在輸入上




react title (16)

呈現組件後,將焦點設置在特定文本字段上的反應方式是什麼?

文檔似乎建議使用引用,例如:

在渲染函數的輸入字段中設置 ref="nameInput" ,然後調用:

this.refs.nameInput.getInputDOMNode().focus(); 

但是我應該在哪裡稱呼它呢? 我已經嘗試了幾個地方,但無法正常工作。


警告:ReactDOMComponent:不要訪問DOM節點的.getDOMNode()。 而是直接使用該節點。 此DOM節點由 App 渲染。

應該

componentDidMount: function () {
  this.refs.nameInput.focus();
}

專注於坐騎

如果只想在掛載(初始渲染)時聚焦某個元素,則只需使用autoFocus屬性即可。

<input autoFocus type="text" />

互動焦點

要有條件地控制焦點,請使用功能組合從組件中隱藏dom和瀏覽器實現的詳細信息。

React 16.8 +功能組件-useFocus掛鉤

componentDidMount() {
    this.refs.linkInput.focus()
}

然後在任何功能組件中使用它。

<input type="text" autoFocus />

Demo

React 16.3 +類組件-exploitFocus

const useFocus = () => {
    const htmlElRef = useRef(null)
    const setFocus = () => {htmlElRef.current &&  htmlElRef.current.focus()}

    return [ setFocus, htmlElRef ] 
}

然後在任何類組件中使用它

const FocusDemo = () => {

    const [value, setValue] = useState("")
    const [setInputFocus, inputRef] = useFocus()
    const [setBtnFocus, btnRef] = useFocus()

    return (
        <> {/* React.Fragment */}

            <input
                value={value}
                onChange={(e)=>{
                    setValue(e.target.value)
                    if ( some logic ){ setBtnFocus() }
                }}
                ref={inputRef}
            />

            <button 
               onClick={setInputFocus}
               ref={btnRef}
            >
               Refocus
            </button>

        </>
    )

}

Demo


AutoFocus最適合我。 我需要雙擊將某些文本更改為帶有該文本的輸入,所以最終得到的結果是:

<input autoFocus onFocus={this.setCaretToEnd} value={this.state.editTodo.value} onDoubleClick={this.updateTodoItem} />

注:要解決React將插入號放置在文本開頭的問題,請使用以下方法:

setCaretToEnd(event) {
    var originalText = event.target.value;
    event.target.value = '';
    event.target.value = originalText;
}

在這裡找到: https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js : https://coderwall.com/p/0iz_zq/how-to-put-focus-at-the-end-of-an-input-with-react-js


React 16.3 通過在組件的構造函數中創建ref並使用如下所示,添加了一種新的便捷方式來處理此問題:

class MyForm extends Component {
  constructor(props) {
      super(props);

      this.textInput = React.createRef();
  }

  componentDidMount() {
    this.textInput.current.focus(); // one important change here is that we need to access the element via current.
  }

  render() {
    // instead of using arrow function, the created ref can be used directly.
    return(
      <div>
        <input ref={this.textInput} />
      </div>
    );
  }
}

有關更多詳細信息,您可以在React博客中查看 此文章

更新:

從React 16.8 開始, useRef 掛鉤可以在功能組件中使用以實現相同的結果:

import React, { useEffect, useRef } from 'react';

const MyForm = () => {
  const textInput = useRef(null);

  useEffect(() => {
    textInput.current.focus();
  }, []);

  return (
    <div>
      <input ref={textInput} />
    </div>
  );
};

在嘗試了許多上述選項但沒有成功之後,我發現這是因為我正在 disabling 然後 enabling 導致焦點丟失的輸入。

我有一個道具 sendingAnswer ,可以在輪詢後端時禁用輸入。

export default class DefaultRolesPage extends React.Component {

    addRole = ev => {
        ev.preventDefault();
        const roleKey = this.roleKey++;
        this::updateState({
            focus: {$set: roleKey},
            formData: {
                roles: {
                    $push: [{
                        id: null,
                        name: '',
                        permissions: new Set(),
                        key: roleKey,
                    }]
                }
            }
        })
    }

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

        return (
            <GridForm onSubmit={this.submit}>
                {formData.roles.map((role, idx) => (
                    <GridSection key={role.key}>
                        <GridRow>
                            <GridCol>
                                <label>Role</label>
                                <TextBox value={role.name} onChange={this.roleName(idx)} autoFocus={role.key === this.state.focus}/>
                            </GridCol>
                        </GridRow>
                    </GridSection>
                ))}
            </GridForm>
        )
    }
}

一旦我移除了禁用的道具,一切都會重新開始。


如果您只想在React中進行自動對焦,那很簡單。

const utilizeFocus = () => {
    const ref = React.createRef()
    const setFocus = () => {ref.current &&  ref.current.focus()}

    return {setFocus, ref} 
}

如果您只是想知道將代碼放在哪裡,答案在componentDidMount()中。

v014.3

class App extends Component {
  constructor(props){
    super(props)
    this.input1Focus = utilizeFocus()
    this.BtnFocus = utilizeFocus()
  }

  render(){
    return (
      <> {/* React.Fragment */}

          <input
              value={value}
              onChange={(e)=>{
                  setValue(e.target.value)
                  if ( some logic ){ this.BtnFocus.setFocus() }
              }}
              ref={this.input1Focus.ref}
          />

          <button 
             onClick={this.input1Focus.setFocus()}
             ref={this.BtnFocus.ref}
          >
             Refocus
          </button>

      </>
    )
  } 
}

在大多數情況下,您可以將引用附加到DOM節點,而完全避免使用findDOMNode。

在此處閱讀API文檔: https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode : https://facebook.github.io/react/docs/top-level-api.html#reactdom.finddomnode


您可以將該方法調用放入render函數中。 或在生命週期方法內, componentDidUpdate


您應該在 componentDidMount 執行此操作,並 refs callback 代替。 像這樣

componentDidMount(){
   this.nameInput.focus(); 
}

class App extends React.Component{
  componentDidMount(){
    this.nameInput.focus();
  }
  render() {
    return(
      <div>
        <input 
          defaultValue="Won't focus" 
        />
        <input 
          ref={(input) => { this.nameInput = input; }} 
          defaultValue="will focus"
        />
      </div>
    );
  }
}
    
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
<div id="app"></div>


我有同樣的問題,但是我也有一些動畫,所以我的同事建議使用window.requestAnimationFrame

這是我元素的ref屬性:

ref={(input) => {input && window.requestAnimationFrame(()=>{input.focus()})}}

更新版本可以 在這裡查看

componentDidMount() {

    // Focus to the input as html5 autofocus
    this.inputRef.focus();

}
render() {
    return <input type="text" ref={(input) => { this.inputRef = input }} />
})


由於此錯誤有很多原因,所以我認為我也應該發布我面臨的問題。 對我來說,問題在於我將輸入內容作為另一個組件的內容來呈現。

 export default ({ Content }) => { return ( <div className="container-fluid main_container"> <div className="row"> <div className="col-sm-12 h-100"> <Content /> // I rendered my inputs here </div> </div> </div> ); } 

這就是我調用上述組件的方式:

 <Component Content={() => { return ( <input type="text"/> ); }} /> 


這不再是最佳答案。 從v0.13 this.refs ,在某些奇怪的情況下, this.refs componentDidMount() 運行之前,可能無法使用 this.refs

只需將 autoFocus 標記添加到您的輸入字段中,如上面的FakeRainBrigand所示。


閱讀幾乎所有答案,但沒有看到 getRenderedComponent().props.input

設置文本輸入參考

this.refs.username.getRenderedComponent().props.input.onChange('');


從React 0.15開始 ,最簡潔的方法是:

<input ref={input => input && input.focus()}/>




reactjs