it-swarm.com.de

wie reagieren programmgesteuerte Eingaben

Ich versuche, einen sehr einfachen Anwendungsfall zu implementieren, eine UI-Funktion, bei der:

  1. Es gibt ein Etikett mit etwas Inhalt
  2. Wenn Sie darauf klicken, wird sie durch eine Texteingabe durch den verfügbaren Inhalt des Labels ersetzt
  3. Der Benutzer kann den Inhalt bearbeiten
  4. Wenn Sie die Eingabetaste drücken, wird die Eingabe ausgeblendet und das Etikett wird mit aktualisiertem Inhalt wieder angezeigt

Ich konnte endlich alles richtig machen (in der Tat mit einem MongoBD-Backend, Redux usw.), und das einzige, was ich nie tun konnte (einen ganzen Tag beim Googeln bezahlen und S.O.F-ähnliche Beiträge lesen) war Folgendes:

Wenn meine Texteingabe angezeigt wird, kann ich den Fokus nicht darauf übertragen. Zuerst habe ich diesen Weg müde:

<div className={((this.state.toggleWordEdit) ? '' : 'hidden')}>
<input id={this.props.Word._id} className="form-control"
        ref="updateTheWord" 
        defaultValue={this.state.Word}
        onChange={this.handleChange}
        onKeyPress={this.handleSubmit}
        autoFocus={this.state.toggleWordEdit}/></div>
    <div className={((this.state.toggleWordEdit) ? 'hidden' : '')}>
      <h3 onClick={this.updateWord}>
        {this.state.Word}</h3>
    </div>

aber der Autofokus funktionierte sicher nicht (ich denke "weil" das Formular gerendert wird, aber im verborgenen Zustand, wodurch der Autofokus unbrauchbar wird). 

Als nächstes versuchte ich in diesem this.updateWor viele Vorschläge, die ich auf google und S.O.F fand:

this.refs.updateTheWord.focus();

was zusammen mit ähnlichen Vorschlägen nicht funktioniert hat. Ich habe auch versucht, React zu täuschen, nur um zu sehen, ob ich überhaupt etwas tun kann! Ich habe echtes DOM benutzt:

    const x = document.getElementById(this.props.Word._id);
    x.focus();

und es hat auch nicht funktioniert. Eine Sache, die ich nicht verstehen konnte, um sie in Word zu fassen, ist ein Vorschlag wie folgt: mit ref als Methode (ich "schätze") Ich habe es nicht einmal probiert, weil ich ein Vielfaches davon habe diese Komponenten und ich brauche ref, um den Wert pro Komponente weiter zu erhalten, und ich konnte mir nicht vorstellen, ob mein Ref nicht benannt wird, wie ich den Wert erhalten könnte!

Könnten Sie mir bitte eine Idee geben, damit ich verstehen kann, dass ich kein Formular verwende (weil ich ein einzelnes Eingabefeld zum Ersetzen eines Labels benötige), wie ich den Fokus setzen könnte, wenn die CSS-Klasse (Bootstrap) verliert. ' versteckt 'bitte?

14
Adrian Adaine

Die Art und Weise, wie Sie Refs verwendet haben, ist nicht die am meisten bevorzugte Methode oder nicht mehr die beste Praxis. versuchen Sie so etwas 

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

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

  render() {

    return (
      <div>
        <input
          type="text"
          ref={(input) => { this.textInput = input; }} />
        <input
          type="button"
          value="Set Focus"
          onClick={this.focus}
        />
      </div>
    );
  }
}

Update
Ab React 16.3 können Sie dieReact.createRef()API verwenden

class MyClass extends React.Component {
  constructor(props) {
    super(props);
    // create a ref to store the textInput DOM element
    this.textInput = React.createRef();
    this.focus = this.focus.bind(this);
  }

  focus() {
    // Explicitly focus the text input using the raw DOM API
    // Note: we're accessing "current" to get the DOM node
    this.textInput.current.focus();
  }

  render() {
    // tell React that we want to associate the <input> ref
    // with the `textInput` that we created in the constructor
    return (
      <div>
        <input
          type="text"
          ref={this.textInput} />
        <input
          type="button"
          value="Set Focus"
          onClick={this.focus}
        />
      </div>
    );
  }
}
24
TRomesh

useFocus hook

// General Focus Hook
const useFocus = (initialFocus = false, id = "") => {
    const [focus, setFocus] = useState(initialFocus)
    const setFocusWithTrueDefault = (param) => setFocus(isBoolean(param)? param : true)
    return ([
        setFocusWithTrueDefault, {
            autoFocus: focus,
            key: `${id}${focus}`,
            onFocus: () => setFocus(true),
            onBlur: () => setFocus(false),
        },
    ])
}


const FocusDemo = () => {

    const [labelStr, setLabelStr] = useState("Your initial Value")
    const [setFocus, focusProps] = useFocus(true)

    return (
        <> {/* React.Fragment */}
            <input
                onChange={(e)=> setLabelStr(e.target.value)}
                value={labelStr}
                {...focusProps}
            />
            <h3 onClick={setFocus}>{labelStr}</h3>
        </>
    )

}

Für eine vollständigere Demo [hier klicken] [1].

0
Ben Carp

Zusätzlich zu den vorherigen Antworten habe ich setTimeout hinzugefügt, damit es funktioniert

handleClick() {


    if (this.searchInput) {
        setTimeout(() => {

            this.searchInput.focus();

        }, 100);
    }
}

dabei ist searchInput die jsx-Referenz der Eingabe

<input
      type="text"
      name="searchText"
      ref={(input) => { this.searchInput = input; }}
      placeholder="Search" />

und die handleClick() ist ein onClick Handler für jedes Element

0
Ali Kleit

Fügen Sie einfach Autofokus Attribut zur input hinzu. (natürlich in JSX ist autoFocus)

<input autoFocus ...
0
Mehdi Dehghani

Verwenden Sie die componentDidUpdate-Methode, um die Komponente jedes Mal zu aktualisieren

componentDidUpdate(prevProps, prevState) {
     this.input.focus();
}
0
Faraz Ahmed