React Native TextInput loses focus on call hook from useState

Environment

react-native: "0.61.5",

"styled-components": "4.4.1"

Reproduction

Snack example: https://snack.expo.io/BJSfYqlCS

import * as React from 'react';
import styled from 'styled-components'
import {View} from 'react-native'

export default () => {
  const [text, setText] = React.useState('');

  const StyledInput = styled.TextInput`
    background-color: red;
    border-color: black;
  `

  return (
    <View>
      <StyledInput value={text} onChangeText={text => setText(text)} />
    </View>
  );
}

Steps to reproduce

type something in styled TextInput

Expected Behavior

Just plain typing

Actual Behavior

lost focus

Upvotes: 2

Views: 992

Answers (2)

Sergey Cherkashin
Sergey Cherkashin

Reputation: 26

Get styles out of function

import * as React from 'react';
import styled from 'styled-components'
import {View} from 'react-native'

const StyledInput = styled.TextInput`
    background-color: red;
    border-color: black;
  `

export default () => {
  const [text, setText] = React.useState('');

  return (
    <View>
      <StyledInput value={text} onChangeText={text => setText(text)} />
    </View>
  );
}

Check expo shack

Upvotes: 1

Gaurav Roy
Gaurav Roy

Reputation: 12195

So the problem is pretty tricky , It looks like the problem is that you're defining your StyledInput inside it's parent return method and then calling the parent's setText method directly (instead of passing through props), which causes rerender that you don't want.

Better approach would be to use direct text input and apply styling to it. Please see below code and also ive shared a working example in expo snack. do check that.

import * as React from 'react';
import styled from 'styled-components'
import {TextInput,View} from 'react-native';

export default () => {
  const [text, setText] = React.useState('');

  const StyledView = styled.View`
    flex: 1;
    align-items:center;
    justify-content: center;
    background-color: papayawhip;
  `

  const StyledInput = styled.TextInput`
    background-color: white;
  `

  const StyledText = styled.Text`
    color: palevioletred;
  `

  return (
    <View>
      <StyledText>Hello World!</StyledText>
      <TextInput style={{height:50,width:50,backgroundColor:'red'}} value={text} onChangeText={text => setText(text)} />
    </View>
  );
}

expo snack expo url

Hope it helps. feel free for doubts

Upvotes: 1

Related Questions