在 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 中添加按钮网格样式?

如何在 React Native expo 的下拉选项中动态获取 api 数据

在功能组件 React native 中动态创建对列表视图中项目的引用

如何在 react-native 中动态加载模块?