Search code examples
javascriptreactjsreact-nativeflatlist

Trying to update array object in React Native


I've made a shorter version of what I'm trying to create for simplicity here. I know some of the code here is wrong. I've spent hours trying different ways and can't get anything to work, so I've stripped it back.

Aim: I'm rendering a FlatList. I need to be able to update the 'qty' in each respective object in the array with the click of a button in each particular FlatList item.

So, if I click 'Increase QTY' in 'abc', then the 'qty' data will be increased by 1.

I've looked everywhere online and can't seem to be able to get any closer. Any help would be hugely appreciated.

import React, { useState } from 'React';
import { View, Text, Button, FlatList } from 'react-native';

const DataApp = () => {
const [data, setData] = useState([
    { id: 1, name: 'abc', qty: 1 },
    { id: 2, name: 'def', qty: 2 },
    { id: 3, name: 'ghi', qty: 3 },
]);

const incQuantityHandler = (data) => {
    setData([...data, prevState => qty[prevState] + 1 ])
}

const Item = ({ item }) => (
    <View>
        <Text>{item.name}</Text>
        <Text>{item.qty}</Text>
        <Button title="Increase QTY" onPress={incQuantityHandler}/>
    </View>
)

const renderItem = ({ item }) => (
    <Item name={item.name} qty={item.qty} />
)

return (
    <View>
        <FlatList
        data={data}
        renderItem={renderItem}
        keyExtractor={item => item.id}
        />
    </View>
)
}

export default DataApp;

Solution

  • With your current setup, incQuantityHandler gets called with an event object whenever the button is pressed. You should use onClick by the way.

    You can use an arrow function to pass on which button you're pressing, otherwise use a wrapper function:

    onClick={() => incQuantityHandler(item.name)}
    // or alternatively, but basically the same:
    const wrapHandler = item => (() => incQuantityHandler(item.name));
    onClick={wrapHandler(item)}
    

    Your incQuantityHandler itself is incorrect. I suggest re-reading the React documentation and learning about array destructuring/spreading, but you probably want something like:

    // Remember that now we get the item name instead
    const incQuantityHandler = (itemName) => {
        // Use an arrow function to mutate data
        setData(data =>
            // Use map to map over all items
            data.map(item => {
                // Leave other items the way they are
                if (item.name !== itemName) return item;
                // Return a modified copy of our target item
                // where we changed the qty field
                return { ...item, qty: item.qty + 1 };
            }));
    }