在 TextInput 中写入一个字符后键盘隐藏问题(Flatlist Header 中的 textinput)
Problem Keyboard hide after write one char in TextInput (textinput inside Flatlist Header)
这个问题我花了两天时间,问题是:
当我将 TextInput 放入 Flatlist 时,TextInput 的行为发生了变化,键盘在输入每个字符后失去焦点。
版本
React-native:0.63.2
反应:16.13.1,
react-dom:16.13.1,
世博会:~42.0.1,
重现步骤
- 我创建了一个名为 ==> [inputSearch, setInputSearch]
的状态变量
- 我在 Flatlist 的 ListHeaderComponent 里面写了一个 textinput
---> 问题是:在键盘中按下每个字符后,键盘隐藏
状态声明:
const [inputSearch, setInputSearch] = useState(null);
TextInput 在 Flatlist 中:
<View style={styles.container}>
<StatusBar
backgroundColor="#11131B"
barStyle="light-content"
/>
<View style={{width: '100%', flex: 1 , backgroundColor: 'white', marginTop: 5}}>
<FlatList
contentContainerStyle={{alignItems: 'center',paddingHorizontal: 20}}
keyExtractor={(item) => (Object.keys(item).length === 0) ? "" : item.id.toString()}
width= {width}
numColumns={2}
ListHeaderComponent={() =>
<View style={{flexDirection:'column',justifyContent:'space-between'}}>
<Text style={{color:Colors.dark1, fontSize:14, marginBottom: 5}}>Search :</Text>
<TextInput style={styles.input} value={inputSearch} onChangeText={setInputSearch} placeholder="Username"/>
</View>
}
data={SIMPLE_DATA}
renderItem={renderItemRow}
>
</FlatList>
</View>
<View>
我要扩展我在评论中写的内容,因为它写得很快而且不够清楚。
让我们考虑以下作为起点(我去掉了无用的信息):
function YourComponent() {
const [inputSearch, setInputSearch] = useState('');
return (
<View>
<StatusBar backgroundColor="#11131B" barStyle="light-content" />
<View>
<FlatList
ListHeaderComponent={() => (
<>
<Text>Search :</Text>
<TextInput
value={inputSearch}
onChangeText={setInputSearch}
placeholder="Username"
/>
</>
)}
data={[]}
renderItem={() => <View />}
/>
</View>
</View>
);
}
每次你调用 setInputSearch
组件都会重新渲染,但这意味着你在 ListHeaderComponent 中内联传递的箭头函数每次都会被调用并且内容会重新创建(键盘关闭)因为焦点所在的输入不再存在,因为它已被新输入取代)。
你怎么解决这个问题? ListHeaderComponent 接受构造函数和 ReactElement,所以你要么传递一个 ReactElement,要么创建一个“独立”组件(没有特定的含义,它只是一个独立的组件,不在另一个组件中)。
这里有几个解决方案:
- ReactElement示例(注意是直接传组件,ListHeaderComponent中没有函数,如果需要也可以将其提取为其他组件):
function YourComponent() {
const [inputSearch, setInputSearch] = useState('');
return (
<View>
<StatusBar backgroundColor="#11131B" barStyle="light-content" />
<View>
<FlatList
ListHeaderComponent={
<>
<Text>Search :</Text>
<TextInput
value={inputSearch}
onChangeText={setInputSearch}
placeholder="Username"
/>
</>
}
data={[]}
renderItem={() => <View />}
/>
</View>
</View>
);
}
- 独立组件(将构造函数传递给 ListHeaderComponent):
function YourComponent() {
return (
<View>
<StatusBar backgroundColor="#11131B" barStyle="light-content" />
<View>
<FlatList
ListHeaderComponent={ListHeaderComponent}
data={[]}
renderItem={() => <View />}
/>
</View>
</View>
);
}
function ListHeaderComponent() {
const [inputSearch, setInputSearch] = useState('');
return (
<>
<Text>Search :</Text>
<TextInput
value={inputSearch}
onChangeText={setInputSearch}
placeholder="Username"
/>
</>
);
}
但这不允许您在 YourComponent 中使用 inputSearch 值。
我希望这有助于解决问题。
这个问题我花了两天时间,问题是:
当我将 TextInput 放入 Flatlist 时,TextInput 的行为发生了变化,键盘在输入每个字符后失去焦点。
版本 React-native:0.63.2 反应:16.13.1, react-dom:16.13.1, 世博会:~42.0.1,
重现步骤
- 我创建了一个名为 ==> [inputSearch, setInputSearch] 的状态变量
- 我在 Flatlist 的 ListHeaderComponent 里面写了一个 textinput
---> 问题是:在键盘中按下每个字符后,键盘隐藏
状态声明:
const [inputSearch, setInputSearch] = useState(null);
TextInput 在 Flatlist 中:
<View style={styles.container}>
<StatusBar
backgroundColor="#11131B"
barStyle="light-content"
/>
<View style={{width: '100%', flex: 1 , backgroundColor: 'white', marginTop: 5}}>
<FlatList
contentContainerStyle={{alignItems: 'center',paddingHorizontal: 20}}
keyExtractor={(item) => (Object.keys(item).length === 0) ? "" : item.id.toString()}
width= {width}
numColumns={2}
ListHeaderComponent={() =>
<View style={{flexDirection:'column',justifyContent:'space-between'}}>
<Text style={{color:Colors.dark1, fontSize:14, marginBottom: 5}}>Search :</Text>
<TextInput style={styles.input} value={inputSearch} onChangeText={setInputSearch} placeholder="Username"/>
</View>
}
data={SIMPLE_DATA}
renderItem={renderItemRow}
>
</FlatList>
</View>
<View>
我要扩展我在评论中写的内容,因为它写得很快而且不够清楚。
让我们考虑以下作为起点(我去掉了无用的信息):
function YourComponent() {
const [inputSearch, setInputSearch] = useState('');
return (
<View>
<StatusBar backgroundColor="#11131B" barStyle="light-content" />
<View>
<FlatList
ListHeaderComponent={() => (
<>
<Text>Search :</Text>
<TextInput
value={inputSearch}
onChangeText={setInputSearch}
placeholder="Username"
/>
</>
)}
data={[]}
renderItem={() => <View />}
/>
</View>
</View>
);
}
每次你调用 setInputSearch
组件都会重新渲染,但这意味着你在 ListHeaderComponent 中内联传递的箭头函数每次都会被调用并且内容会重新创建(键盘关闭)因为焦点所在的输入不再存在,因为它已被新输入取代)。
你怎么解决这个问题? ListHeaderComponent 接受构造函数和 ReactElement,所以你要么传递一个 ReactElement,要么创建一个“独立”组件(没有特定的含义,它只是一个独立的组件,不在另一个组件中)。
这里有几个解决方案:
- ReactElement示例(注意是直接传组件,ListHeaderComponent中没有函数,如果需要也可以将其提取为其他组件):
function YourComponent() {
const [inputSearch, setInputSearch] = useState('');
return (
<View>
<StatusBar backgroundColor="#11131B" barStyle="light-content" />
<View>
<FlatList
ListHeaderComponent={
<>
<Text>Search :</Text>
<TextInput
value={inputSearch}
onChangeText={setInputSearch}
placeholder="Username"
/>
</>
}
data={[]}
renderItem={() => <View />}
/>
</View>
</View>
);
}
- 独立组件(将构造函数传递给 ListHeaderComponent):
function YourComponent() {
return (
<View>
<StatusBar backgroundColor="#11131B" barStyle="light-content" />
<View>
<FlatList
ListHeaderComponent={ListHeaderComponent}
data={[]}
renderItem={() => <View />}
/>
</View>
</View>
);
}
function ListHeaderComponent() {
const [inputSearch, setInputSearch] = useState('');
return (
<>
<Text>Search :</Text>
<TextInput
value={inputSearch}
onChangeText={setInputSearch}
placeholder="Username"
/>
</>
);
}
但这不允许您在 YourComponent 中使用 inputSearch 值。
我希望这有助于解决问题。