Das Eingabefeld "Reagieren" verliert beim Filtern von Daten den Fokus


8

Ich habe eine Liste von Arrays und wenn ich anfange, in die inputListe von Arrays einzugeben, wird entsprechend gefiltert value. Es funktioniert, aber ich verliere den Fokus, inputnachdem ich ein Zeichen eingegeben habe.

Mein Code:

const MyPage = (props) => {

  const [searchTerm, setSearchTerm] = useState("");

  const results = !searchTerm
      ? people
      : people.filter(person =>
          person.toLowerCase().includes(searchTerm.toLocaleLowerCase())
        );

  const handleChange = event => {
      setSearchTerm(event.target.value);
    };

  const Desktop = ({ children }) => {
    const isDesktop = useMediaQuery({ minWidth: 992 })

    return (
      isDesktop?
      <View>
          <input
          type="text"
          placeholder="Search"
          value={searchTerm}
          onChange={handleChange}
          />
          <View style={{width:100, height:100, backgroundColor:'red'}}>
            {results.map(item => (
              <Text>{item}</Text>
            ))}
          </View>
      </View>
      :null
    )
  }

  return(
    <View style={{width:'100%',justifyContent:'center'}}>
      <Desktop/>
    </View>
  )
}

Anstatt zurückzukehren, <Desktop/>wenn ich direkt setze

<input
          type="text"
          placeholder="Search"
          value={searchTerm}
          onChange={handleChange}
          />
          <View style={{width:100, height:100, backgroundColor:'red'}}>
            {results.map(item => (
              <Text>{item}</Text>
            ))}
          </View>

Es wird klappen. Irgendeine Idee, wie man dieses Problem behebt?

Jeder Rat oder Kommentar wird geschätzt!

Danke im Voraus!


Ich denke, setzen Sie Ihre isDesktop-Variable außerhalb des Komponentenbereichs und verwenden Sie useCallback, um Ihre handleChange-Funktion zu verpacken
Harish Jangra

@ HarishJangra danke für den Kommentar Ich weiß jetzt nicht wirklich viel über useCallback Könntest du mir zeigen wie?
Kirimi

Antworten:


6

Durch Verschieben der DesktopKomponente außerhalb derMyApp Komponente wird dieses Problem behoben. Der Hauptgrund dafür ist, dass die DesktopKomponente bei jedem Rendern (bei jeder Eingabe) neu erstellt wird, wodurch das Eingabeelement seinen Fokus verliert. Sie können dies auch etwas abmildern, indem Sie die Hooks useCallbackund verwenden useMemo, die beide in der offiziellen React-Dokumentation ausführlich beschrieben sind. In diesem Beispiel werden sie jedoch nicht benötigt.

Siehe auch diese Antwort zum Deklarieren anderer Komponenten innerhalb einer Komponente .



0

Auch als Hacky-Trick können Sie die autoFocusEigenschaft Ihrer Eingabe verwenden:

        <input
          autoFocus={true}
          type="text"
          placeholder="Search"
          value={searchTerm}
          onChange={handleChange}
    />

0

Das Problem ist, dass Sie eine Komponente in einer Komponente haben. Wenn sich Ihr Status ändert, wird die DesktopKomponente neu initialisiert , wodurch der inputFokus verloren geht. Ich habe beide Komponenten in einer zusammengeführt. Wenn Sie tatsächlich eine Desktopeigene Komponente sein müssen, möchten Sie diese möglicherweise Desktopaußerhalb von deklarieren MyPageund searchTerm, results, handleChangeals Requisiten an übergeben Desktop.

const MyPage = props => {
  const [searchTerm, setSearchTerm] = useState("");
  const isDesktop = useMediaQuery({ minWidth: 992 });

  const results = !searchTerm
    ? people
    : people.filter(person =>
        person.toLowerCase().includes(searchTerm.toLocaleLowerCase())
      );

  const handleChange = event => {
    setSearchTerm(event.target.value);
  };

  return (
    <View style={{ width: "100%", justifyContent: "center" }}>
      {isDesktop && (
        <View>
          <input
            type="text"
            placeholder="Search"
            value={searchTerm}
            onChange={handleChange}
          />
          <View style={{ width: 100, height: 100, backgroundColor: "red" }}>
            {results.map(item => (
              <Text>{item}</Text>
            ))}
          </View>
        </View>
      )}
    </View>
  );
};
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.