最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Add items to FlatList dynamically in React Native - Stack Overflow

programmeradmin3浏览0评论

I have a FlatList with two items. I need to append this list with another elements. When the user clicks on the button, the data from the text inputs should appear in the end of the FlatList. So, I've tried to push data object to the end of the list's array, but new item replaces the last one.

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
  },
});

I have a FlatList with two items. I need to append this list with another elements. When the user clicks on the button, the data from the text inputs should appear in the end of the FlatList. So, I've tried to push data object to the end of the list's array, but new item replaces the last one.

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
  },
});
Share Improve this question edited Apr 6, 2020 at 8:20 Amphyx asked Apr 6, 2020 at 6:54 AmphyxAmphyx 7554 gold badges13 silver badges29 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 11

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
  },
});

You are just changing the listElements array. This will NOT trigger the re rendering of the component and hence the flat list will be unchanged.

Create a state variable in the component and store your data in that so that any modification results in re rendering.

I fixed the problem of replacing elements by changing array into a state variable.

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
  },
});

i fixed it by defining the array outside the export function

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;

this was part of an larger app, but it should do the trick, I hope it helps

发布评论

评论列表(0)

  1. 暂无评论