在 React Native 中动态添加项目到 FlatList
Posted
技术标签:
【中文标题】在 React Native 中动态添加项目到 FlatList【英文标题】:Add items to FlatList dynamically in React Native 【发布时间】:2020-07-18 03:12:55 【问题描述】:我有一个包含两个项目的 FlatList。我需要在这个列表中附加其他元素。当用户单击按钮时,来自文本输入的数据应出现在 FlatList 的末尾。因此,我尝试将数据对象推送到列表数组的末尾,但新项目替换了最后一个。
import React, useState from 'react';
import Text, View, StyleSheet, Button from 'react-native';
import FlatList from 'react-native-gesture-handler';
export default function HomeScreen()
var initialElements = [
id : "0", text : "Object 1",
id : "1", text : "Object 2",
]
const [exampleState, setExampleState] = useState(initialElements);
const [idx, incr] = useState(2);
const addElement = () =>
var newArray = [...initialElements , id : toString(idx), text: "Object " + (idx+1) ];
initialElements.push(id : toString(idx), text: "Object " + (idx+1) );
incr(idx + 1);
setExampleState(newArray);
return (
<View style=styles.container>
<FlatList
keyExtractor = item => item.id
data=exampleState
renderItem = item => (<Text>item.item.text</Text>) />
<Button
title="Add element"
onPress=addElement />
</View>
);
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#fff',
width: '100%',
borderWidth: 1
,
);
【问题讨论】:
【参考方案1】:我通过在导出函数之外定义数组来修复它
import React, useState from 'react'
import StyleSheet, View, TextInput, TouchableOpacity, Text, FlatList from 'react-native'
let tipArray = [
key: '1', tip: 20,
key: '2', tip: 12
]
const screen = function tipInputScreen( navigation )
const [ tip, setTip ] = useState('')
const addTip = ()=>
if(tip == "")return
tipArray.push(key: (tipArray.length + 1).toString(), tip)
setTip('')
const logInput = (input)=>
setTip(input)
const renderTip = ( item ) =>
return(
<TouchableOpacity style=styles.listItem>
<Text style=styles.buttonText>`$item.tip $`</Text>
</TouchableOpacity>)
return (
<View
style=styles.background>
<TextInput
style=styles.input
keyboardType='number-pad'
keyboardAppearance='dark'
onChangeText=logInput
value=tip
/>
<TouchableOpacity
style=styles.redButton
onPress=addTip>
<Text style=styles.buttonText>Add Tip</Text>
</TouchableOpacity>
<FlatList
data=tipArray
renderItem=renderTip
style=styles.flatList
/>
</View>
)
const styles = StyleSheet.create(
background:
backgroundColor: 'grey',
paddingTop: Platform.OS === "android" ? 25:0,
width: '100%',
height: '100%',
alignItems: 'center'
,
input:
marginTop:40,
color:'white',
fontSize:30,
backgroundColor: "#2e2a2a",
height: 50,
width: '90%',
textDecorationColor: "white",
borderColor: 'black',
borderWidth: 2
,
flatList:
width: "100%"
,
listItem:
width: "90%",
height: 50,
backgroundColor: "#2e2e2e",
borderRadius: 25,
marginVertical: 4,
marginHorizontal: "5%",
justifyContent: "center"
,
listItemTitle:
color: "white",
textAlign: "center",
fontSize: 18
,
redButton:
justifyContent: "center",
width: "90%",
height: 50,
backgroundColor: "red",
borderRadius: 25,
marginHorizontal: 20,
marginVertical: 10
,
buttonText:
color: "white",
textAlign: "center",
fontSize: 18
)
export default screen;
这是一个更大的应用程序的一部分,但它应该可以解决问题,我希望它有所帮助
【讨论】:
【参考方案2】:我通过将数组更改为状态变量来解决替换元素的问题。
import React, useState from 'react';
import Text, View, StyleSheet, Button from 'react-native';
import FlatList from 'react-native-gesture-handler';
export default function HomeScreen()
const [initialElements, changeEl] = useState([
id : "0", text : "Object 1",
id : "1", text : "Object 2",
]);
const [exampleState, setExampleState] = useState(initialElements);
const [idx, incr] = useState(2);
const addElement = () =>
var newArray = [...initialElements , id : idx, text: "Object " + (idx+1) ];
incr(idx + 1);
console.log(initialElements.length);
setExampleState(newArray);
changeEl(newArray);
return (
<View style=styles.container>
<FlatList
keyExtractor = item => item.id
data=exampleState
renderItem = item => (<Text>item.item.text</Text>) />
<Button
title="Add element"
onPress=addElement />
</View>
);
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#fff',
width: '100%',
borderWidth: 1
,
);
【讨论】:
【参考方案3】:import React, useState from 'react';
import Text, View, StyleSheet, Button from 'react-native';
import FlatList from 'react-native-gesture-handler';
export default function HomeScreen()
var initialElements = [
id : "0", text : "Object 1",
id : "1", text : "Object 2",
]
const [exampleState, setExampleState] = useState(initialElements)
const addElement = () =>
var newArray = [...initialElements , id : "2", text: "Object 3"];
setExampleState(newArray);
return (
<View style=styles.container>
<FlatList
keyExtractor = item => item.id
data=exampleState
renderItem = item => (<Text>item.item.text</Text>) />
<Button
title="Add element"
onPress=addElement />
</View>
);
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#fff',
width: '100%',
borderWidth: 1
,
);
您只是在更改 listElements 数组。这不会触发组件的重新渲染,因此平面列表将保持不变。
在组件中创建一个 state 变量并将您的数据存储在其中,以便任何修改都会导致重新渲染。
【讨论】:
对不起,我是 React Native 开发的新手。如何在数组中创建状态变量? 好的,它有效。但是当我在添加第三个元素之后添加新元素时,它会替换最后一个元素并且不会附加到列表中。所以,我不能在列表中添加超过 3 个项目。 我使用了不同的 id,但只有一项出现在列表底部。我更新了我的答案,你可以查看我的新代码。以上是关于在 React Native 中动态添加项目到 FlatList的主要内容,如果未能解决你的问题,请参考以下文章
从 React Native Text Input 向 Redux Toolkit 的 createApi 添加动态数据?
console.error: "react-native-maps" AirGoogleMaps 目录必须添加到您的 xCode 项目中
如何在 React Native expo 的下拉选项中动态获取 api 数据