campo de entrada de reação perderá o foco ao filtrar dados


8

Eu tenho uma lista de matriz e quando eu começar a digitar na inputlista de matriz irá filtrar correspondente ao value. Funciona, mas perco o foco inputdepois de digitar um caractere.

Meu código:

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>
  )
}

Em vez de retornar <Desktop/>se eu colocar diretamente

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

Vai funcionar. Alguma idéia de como corrigir esse problema?

Qualquer conselho ou comentário será apreciado!

Desde já, obrigado!


Eu acho que coloque sua variável isDesktop fora do escopo do componente e use useCallback para quebrar sua função handleChange
Harish Jangra

@ HarishJangra obrigado pelo comentário Eu realmente não tenho muita informação sobre useCallback, você poderia me mostrar como?
kirimi 6/02

Respostas:


6

Mover o Desktopcomponente para fora doMyApp componente corrige esse problema. A principal razão para isso é que o Desktopcomponente é recriado em cada renderização (toda vez que você digita), o que faz com que o elemento de entrada perca seu foco. Você também pode atenuar isso usando os ganchos useCallbacke useMemo, ambos descritos em detalhes na documentação oficial do React , mas neste exemplo eles não são necessários.

Veja também esta resposta ao declarar outros componentes dentro de um componente .



0

Também como truque hacky, você pode usar a autoFocuspropriedade de sua entrada:

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

0

O problema é que você tem um componente dentro de um componente. Portanto, quando seu estado muda, o Desktopcomponente é reinicializado , o que faz com que o inputfoco seja perdido. Mesclei os dois componentes em um. Se você realmente precisar Desktopser seu próprio componente, poderá declarar Desktopfora MyPagee passar searchTerm, results, handleChangecomo adereços para 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>
  );
};
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.