Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React Get state of native elemet

I am making my custom components that wrap react-native components. I am currently making MyInput component. It uses TextInput component.I want to know state of TextInput component, but i dont want to use onFocus or onBlur etc. I am trying to pass all of those props trough. I am currently trying with using refs, but it is not working properly because there is delay. "isFocused" only turns true when I start typing, not on click. Is there some good way to solve this?

interface InputProps extends TextInputProps {
}
export const Input = ({
  children,
  ...props
}: PropsWithChildren<InputProps>) => {
  const { themeStyles } = useContext(ThemeContext);
  const { styles } = useStyles(themeStyles);
  const inputRef = useRef<TextInput>(null);
  const isFocused = inputRef.current?.isFocused(); // not working properly
  return (
    <View style={[styles.inputContainer]}>
      <TextInput ref={inputRef} {...props} style={[styles.input, isFocused && styles.blueText]}>
        {children}
      </TextInput>
    </View>
  );
};

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

To be honest with you, I don’t see a good way of doing this without using onFocus and onBlur. Your isFocused variable is only updating when your component re-renders, which is why you’re seeing the behavior you don’t like.

You could try this, but I’m not sure that it’s ideal or will generate the desired results:

export const Input = ({
  children,
  ...props
}: PropsWithChildren<InputProps>) => {
  const { themeStyles } = useContext(ThemeContext);
  const { styles } = useStyles(themeStyles);
  const inputRef = useRef<TextInput>(null);
  // const isFocused = inputRef.current?.isFocused(); // not working properly

  return (
    <View style={[styles.inputContainer]}>
      <TextInput ref={inputRef} {...props} style={[styles.input, inputRef.current?.isFocused() && styles.blueText]}>
        {children}
      </TextInput>
    </View>
  );
};

I don’t know what your restrictions are, but based on your description, I might try merging the onFocus and onBlur props passed to Input with internal functions that set the desired styles. Something like this:

export const Input = ({
  children,
  onFocus,
  onBlur,
  ...props
}: PropsWithChildren<InputProps>) => {
  const { themeStyles } = useContext(ThemeContext);
  const { styles } = useStyles(themeStyles);
  const inputRef = useRef<TextInput>(null);

  const [focusedStyle, setFocusedStyle] = useState(undefined);
  
  const onInputFocus = useCallback((e) => {
    onFocus(e);
    setFocusedStyle(styles.blueText);
  }, [onFocus]);
  const onInputBlur = useCallback((e) => {
    onBlur(e);
    setFocusedStyle(undefined);
  }, [onBlur]);

  return (
    <View style={[styles.inputContainer]}>
      <TextInput ref={inputRef} {...props} style={[styles.input, focusedStyle]} onFocus={onInputFocus} onBlur={onInputBlur}>
        {children}
      </TextInput>
    </View>
  );
};

Alternatively, have you considered using a library like React Native Paper? It’s TextInput component handles this for you, and exposes props for both focused/unfocused styling.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading