reactjs شرح - رد فعل ضبط التركيز على المدخلات بعد تقديم




ماهو ترجمة (16)

تحتوي مستندات React الآن على قسم لهذا الغرض. https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute

 render: function() {
  return (
    <TextInput
      ref={function(input) {
        if (input != null) {
          input.focus();
        }
      }} />
    );
  },

ما هي طريقة التفاعل لتحديد التركيز على حقل نص معين بعد أن يتم عرض المكون؟

يبدو أن المستندات تقترح استخدام حالات المراجعة ، على سبيل المثال:

قم بتعيين ref="nameInput" على حقل الإدخال الخاص بي في وظيفة العرض ، ثم اتصل:

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

لكن أين يجب أن أسمي هذا؟ لقد جربت بعض الأماكن ولكن لا يمكنني الحصول عليها للعمل.


هذه هي الطريقة الصحيحة ، وكيفية ضبط تلقائي للصورة. عند استخدام رد الاتصال بدلاً من سلسلة كقيمة ref ، يتم استدعائه تلقائيًا. حصلت على المرجع الخاص بك دون الحاجة إلى لمس DOM باستخدام getDOMNode

render: function() {
  return <TextInput ref={(c) => this._input = c} />;
},
componentDidMount: function() {
  this._input.focus();
},

هذا لم يعد أفضل إجابة. اعتبارًا من v0.13 ، قد لا يتوفر هذا الملف. حتى يتم تشغيل AFTER componentDidMount() في بعض الحالات الفردية.

ما عليك autoFocus إضافة علامة autoFocus إلى حقل الإدخال ، كما هو موضح في FakeRainBrigand أعلاه.


قراءة تقريبا كل الاجابة ولكن لم يشاهد getRenderedComponent().props.input

تعيين إعادة إدخال النص الخاص بك

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


يعمل 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


اعتبارًا من React 0.15 ، فإن الطريقة الأكثر إيجازًا هي:

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

أبسط الإجابة هي إضافة ref = "some name" في عنصر إدخال النص واستدعاء الدالة أدناه.

componentDidMount(){
   this.refs.field_name.focus();
}
// here field_name is ref name.

<input type="text" ref="field_name" />

لدي نفس المشكلة ولكن لدي بعض الرسوم المتحركة أيضًا ، لذلك يقترح زميلي استخدام window.requestAnimationFrame

هذه سمة ref من عنصري:

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

جواب ديراج هو الصحيح ، ولكن من أجل الراحة يمكنك استخدام خاصية autoFocus للدفع للحصول على مدخلات يتم التركيز عليها تلقائيًا عند تركيبها.

<input autoFocus name=...

أنا فقط ركض في هذه المسألة وأنا باستخدام رد 15.0.1 15.0.2 وأنا باستخدام ES6 وبناء الجملة لم تحصل على ما احتاجه من الإجابات الأخرى منذ v.15 أسقطت منذ أسابيع ، وبعض من this.refs تم إيقاف خصائص this.refs removed .

بشكل عام ، ما احتاجه هو:

  1. ركّز على عنصر الإدخال (الحقل) الأول عند تثبيت المكون
  2. التركيز على عنصر الإدخال (الحقل) الأول مع وجود خطأ (بعد الإرسال)

أنا استخدم:

  • React Container / Presentation Component
  • مسترجع
  • الرد-راوتر

التركيز على عنصر الإدخال الأول

لقد استخدمت autoFocus={true} في أول <input /> على الصفحة بحيث عند تثبيت المكون ، سيحصل على التركيز.

التركيز على عنصر الإدخال الأول مع وجود خطأ

استغرق هذا وقتا أطول وكان أكثر تعقيدا. أحتفظ برمز لا يتعلق بالحل للإيجاز.

Redux Store / State

أحتاج إلى حالة عالمية لمعرفة ما إذا كان ينبغي ضبط التركيز وتعطيله عند تعيينه ، لذلك لا أحتفظ بإعادة ضبط التركيز عند إعادة عرض componentDidUpdate() للبحث عن ضبط التركيز.)

يمكن تصميم ذلك كما تراه مناسبًا لتطبيقك.

{
    form: {
        resetFocus: false,
    }
}

مكون الحاوية

سيحتاج المكون إلى تعيين الخاصية resetfocus و callBack لمسح الخاصية إذا كان إعداد التركيز على نفسه.

لاحظ أيضًا أني قمت بتنظيم منشئي العمل في ملفات منفصلة ، ويرجع ذلك في الغالب إلى أن مشروعي كبير إلى حد كبير وأردت تقسيمه إلى أجزاء أكثر قابلية للإدارة.

import { connect } from 'react-redux';
import MyField from '../presentation/MyField';
import ActionCreator from '../actions/action-creators';

function mapStateToProps(state) {
    return {
        resetFocus: state.form.resetFocus
    }
}

function mapDispatchToProps(dispatch) {
    return {
        clearResetFocus() {
            dispatch(ActionCreator.clearResetFocus());
        }
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(MyField);

مكون العرض التقديمي

import React, { PropTypes } form 'react';

export default class MyField extends React.Component {
    // don't forget to .bind(this)
    constructor(props) {
        super(props);
        this._handleRef = this._handleRef.bind(this);
    }

    // This is not called on the initial render so
    // this._input will be set before this get called
    componentDidUpdate() {
        if(!this.props.resetFocus) {
            return false;
        }

        if(this.shouldfocus()) {
            this._input.focus();
            this.props.clearResetFocus();
        }
    }

    // When the component mounts, it will save a 
    // reference to itself as _input, which we'll
    // be able to call in subsequent componentDidUpdate()
    // calls if we need to set focus.
    _handleRef(c) {
        this._input = c;
    }

    // Whatever logic you need to determine if this
    // component should get focus
    shouldFocus() {
        // ...
    }

    // pass the _handleRef callback so we can access 
    // a reference of this element in other component methods
    render() {
        return (
            <input ref={this._handleRef} type="text" />
        );
    }
}

Myfield.propTypes = {
    clearResetFocus: PropTypes.func,
    resetFocus: PropTypes.bool
}

نظرة عامة

والفكرة العامة هي أن كل حقل نموذج يمكن أن يكون به خطأ وأن يركز على الحاجات ليتحقق من نفسه وإذا احتاج إلى التركيز على نفسه.

هناك منطق عمل يجب أن يحدث لتحديد ما إذا كان الحقل المعطى هو الحقل المناسب لتعيين التركيز عليه. لا يتم عرض ذلك لأنه يعتمد على التطبيق الفردي.

عند إرسال نموذج ، يحتاج هذا الحدث إلى تعيين resetFocus التركيز العامة resetFocus إلى true. وبعد تحديث كل مكون لنفسه ، سيشاهد أنه ينبغي عليه التحقق لمعرفة ما إذا كان يتم التركيز عليه ، وإذا تم ذلك ، فأرسل الحدث لإعادة ضبط التركيز حتى لا تضطر عناصر أخرى إلى مواصلة التحقق.

تحرير كملاحظة جانبية ، كان لدي منطق عملي في ملف "الأدوات المساعدة" ، وقمت بتصدير الطريقة shouldfocus() عليها في كل طريقة shouldfocus() .

في صحتك!


المرجع. تعليق دايف على جواب ديراج. بديل هو استخدام وظيفة رد الاتصال للسمة ref على العنصر الذي يتم تقديمه (بعد عرض المكون أولاً):

<input ref={ function(component){ React.findDOMNode(component).focus();} } />

مزيد من المعلومات


يجب عليك القيام بذلك في 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>


نسخة محدثة يمكنك التحقق هنا

componentDidMount() {

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

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

لا تحتاج getInputDOMNode ؟ في هذه الحالة...

فقط ببساطة الحصول على ref focus() عندما يحصل على تركيب المكون - componentDidMount ...

import React from 'react';
import { render } from 'react-dom';

class myApp extends React.Component {

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

  render() {
    return(
      <div>
        <input ref={input => { this.nameInput = input; }} />
      </div>
    );
  }

}

ReactDOM.render(<myApp />, document.getElementById('root'));

يمكنك وضع استدعاء الأسلوب هذا داخل وظيفة التجسيد. أو داخل طريقة دورة الحياة ، componentDidUpdate


من خلال الاستفادة من ReactOO ، يمكنك بسهولة استخدام الميراث ( إخلاء المسؤولية : أنا مؤلف ReactOO ):

(function () {

    // Class definitions. ReactOO requires class definition first just like you did in an OO way.

    window.Vehicle = window.ReactOO.ReactBase.extend({
        getReactDisplayName: function () {
            return 'Vehicle';
        },

        onReactRender: function (reactInstance) {
            var self = this;

            var text = self.methodC();

            return React.createElement('div', {}, text);
        },

        methodA: function () {
            console.log('Vehicle method A');
        },

        methodB: function () {
            console.log('Vehicle method B');
        },

        methodC: function () {
            return 'Vehicle method C';
        }
    });

    window.Airplane = window.Vehicle.extend({
        getReactDisplayName: function () {
            return 'Airplane';
        },

        methodC: function () {
            // Call this._super() to execute parent method.
            //this._super();
            return 'Airplane method C';
        }
    });

    var vehicle = new window.Vehicle();
    vehicle.render({}, '#vehicle');

    var airPlane = new window.Airplane();
    airPlane.render({}, '#airPlane');
})();
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>ReactOO Vehicle-Aireplane Example</title>
    <link rel="stylesheet" href="css/base.css" />
    <script src="scripts/react.js"></script>
    <script src="scripts/react-dom.js"></script>
    <script src="../src/reactoo.js"></script>
</head>
<body>
    <div id="vehicle">
    </div>
    <div id="airPlane">
    </div>
    <script src="scripts/vehicleAirplane.js">
    </script>
</body>
</html>





reactjs