Reputation: 175
When I move a TextInput into a custom JSX component it loses focus as soon as I modify the text.
In the example below a near identical TextInput is also created in render() without using a component tag and it does not lose focus.
I have read about the key attribute and how focus can be lost if this is not specified or not unique. However, in the simple example below key attributes are unique.
import React, { Component } from 'react'
import {
AppRegistry,
Text,
View,
TextInput,
} from 'react-native'
class App extends Component {
constructor(props) {
super(props);
this.state = {
text: "111"
};
}
render() {
var t = this;
function Dynamic(props) {
var text = props.text;
return <TextInput key="textinput1" style={{width:"100%", padding:10,
borderWidth:1, marginTop:20, marginBottom:20}}
onChangeText={(text) => { t.setState({text}) } }
value={text}
/>
}
return (
<View >
<Text>DYNAMIC COMPOMENT - LOSES FOCUS</Text>
<Dynamic key="dynamickey" text={this.state.text}></Dynamic>
<Text>NOT DYNAMIC - KEEPS FOCUS</Text>
<TextInput key="textinput2" style={{width:"100%", padding:10,
borderWidth:1, marginTop:20, marginBottom:20}}
onChangeText={(text) => { t.setState({text}) } }
value={this.state.text}
/>
</View>
)
}
}
AppRegistry.registerComponent('App', () => App)
Any input on what is happening here or how to deal with it would be very much appreciated.
Upvotes: 7
Views: 10848
Reputation: 408
It looks like the problem is that you're defining your Dynamic inside it's parent render method and then calling the parent's setState method directly (instead of passing through props), which causes rerender that you don't want. Try it like this:
import React, { Component } from "react";
import { AppRegistry, Text, View, TextInput } from "react-native";
class App extends Component {
constructor(props) {
super(props);
this.state = {
text: "111"
};
}
render() {
var t = this;
return (
<View>
<Text>DYNAMIC COMPOMENT - LOSES FOCUS</Text>
<Dynamic
key="dynamickey"
text={this.state.text}
changeText={text => this.setState({ text })}
/>
<Text>NOT DYNAMIC - KEEPS FOCUS</Text>
<TextInput
key="textinput2"
style={{
width: "100%",
padding: 10,
borderWidth: 1,
marginTop: 20,
marginBottom: 20
}}
onChangeText={text => {
t.setState({ text });
}}
value={this.state.text}
/>
</View>
);
}
}
const Dynamic = ({ text, changeText }) => {
return (
<TextInput
key="textinput1"
style={{
width: "100%",
padding: 10,
borderWidth: 1,
marginTop: 20,
marginBottom: 20
}}
onChangeText={changeText}
value={text}
/>
);
};
AppRegistry.registerComponent("App", () => App);
Here is a working sample: https://snack.expo.io/BJ-SARfdM
Upvotes: 10