简体   繁体   中英

React Native TextInput ReRenders when calling useState Hook inside a custom component

Description When a TextInput component triggers action such as in onChangeText or onKeyPress method which then triggers setState, the component will re render and lose focuse.

React Native version: 0.62 (Unable to upgrade due to use of Expo)

Steps To Reproduce Provide a detailed list of steps that reproduce the issue.

  1. Create a Custom Wrapper Component simple like
  2. Declare useStateHook
  3. Pass TextInput to the Wrapper Component either by direct JSX or Custom Component
  4. Bind setState function to any of event listeners of TextInput.

Expected Results sets State but does not lose focus or rerenders

Snack, code example, screenshot, or link to a repository: Expo Example https://snack.expo.io/@ksi9302/1f9369

Hi Guys, this is a bug report I made to React Native. But I'm not sure if I'm doing something wrong here.

What I've tried so far and doesn't work

  1. Get rid of all styles.
  2. make custom input component with class react component, disable shouldComponentUpdate
  3. not binding value
  4. make different state structure and actually pass within object {}
  5. make dummy key

What I know will work

  • Get rid of custom wrapper and use plain JSX (In other words, not passing TextInput as children component) //Almost impossible when app gets bigger

Bad Compromise

  • using AutoFocus={true} //on Web works fine, but on Mobile, keyboard flickers a lot.

Take the wrapper out as it keeps getting rerendered due to the search value changes.

import React, { useState } from "react";
import { View, TextInput } from "react-native";

const Test = () => {
  const handleChange = e => {
    setSearch(e);
  };
  const [search, setSearch] = useState(null);

  return (
    <Wrapper>
      <TextInput
        value={search}
        onChangeText={e => {
          handleChange(e);
        }}
        placeholder="type here"
      />
    </Wrapper>
  );
};

const Wrapper = props => {
    return (
      <View
        style={{
          width: "100%",
          height: "100%",
          alignItems: "center",
          justifyContent: "center",
          display: "flex",
        }}
      >
        {props.children}
      </View>
    );
  };

export default Test;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM