0

I have the following view in a React Native app:

enter image description here

And this is the code for it: index.js

import React, {useContext} from 'react';
import {View, StyleSheet} from 'react-native';
import {Headline, Button, IconButton} from 'react-native-paper';
import ShoppingCartEntry from './ShoppingCartEntry';
import ShoppingCartContext from '../../context/shoppingCart/shoppingCartContext';

const ShoppingCartList = () => {
  const {shoppingCart} = useContext(ShoppingCartContext);

  const TotalPriceDisplay = () => {
    let totalPrice = 0;

    shoppingCart.map((entry) => {
      totalPrice = totalPrice + (entry.product.price * entry.amount);
    })

    return (
      <Headline>Total: {totalPrice}</Headline>
    )
  }

  return (
    <View style={styles.cartContainer}>
      <View style={styles.icon}>
        <IconButton icon='cart' color='black' size={40}/>
      </View>
      {shoppingCart.map((entry) => {
        return (
          <ShoppingCartEntry entry={entry} />
        )
      })}
      <View style={styles.totalPrice}>
        <TotalPriceDisplay />
        <Button mode='contained'>
          Comprar
        </Button>
      </View>
    </View>
  )
}

styles = StyleSheet.create({
  cartContainer: {
    flexDirection: 'column',
  },
  totalPrice: {
    alignItems: 'center'
  },
  icon: {
    alignItems: 'center'
  }
})

export default ShoppingCartList;

ShoppingCartEntry.js

import React, {useContext} from 'react';
import {View, StyleSheet} from 'react-native';
import {Headline, IconButton, Text} from 'react-native-paper';
import ShoppingCartContext from '../../context/shoppingCart/shoppingCartContext';

const ShoppingCartEntry = ({entry}) => {
  const {shoppingCartAppendProduct, shoppingCartUpdateProduct, shoppingCartRemoveProduct} = useContext(ShoppingCartContext);
  
  const removeProduct = () => {
    shoppingCartRemoveProduct(entry.product.id);
  }

  const Counter = () => {
    return (
      <View style={styles.counterContainer}>
        <View style={styles.counter}>
          <IconButton icon='plus' color='black' onPress={removeProduct} />
        </View>
        <View>
          <Headline color='blue'>{entry.amount}</Headline>
        </View>
        <View style={styles.counter}>
          <IconButton icon='minus' color='black' onPress={removeProduct} />
        </View>
      </View>
    )
  }

  return (
    <View style={styles.entryContainer}>
      <View style={styles.button}>
        <IconButton icon='delete' color='red' onPress={removeProduct} />
      </View>
      <View style={styles.name}>
        <Headline>{entry.product.name}</Headline>
        <Text>{entry.product.price}</Text>
      </View>
      <View style={styles.amount}> 
        <Counter />
        <Text style={{textAlign: 'right'}}>{entry.product.price * entry.amount}</Text>
      </View>
    </View>
  )
}

styles = StyleSheet.create({
  entryContainer: {
    flexDirection: 'row',
    paddingBottom: 20,
    paddingLeft: 20
  },
  name: {
    flex: 0.5
  },
  amount: {
    flex: 0.3
  },
  button: {
    alignItems: 'flex-end',
    flex: 0.1
  },
  counterContainer: {
    flexDirection: 'row'
  },
  counter: {
    alignItems: 'flex-end',
    justifyContent: 'center',
    flexDirection: 'row'
  }
})

export default ShoppingCartEntry;

The problem is that when an element is removed from shoppingCart and the whole view is re rendered, it looses all its formatting:

enter image description here

I discovered that all I have to do is to change the StyleSheet.flexDirection for the container from row to column and, then, back to row again, and the view gets arranged again, but now with the new data.

I don't know if this is a development stage issue that I shouldn't care about for production, or if there is something I can do to avoid it.

HuLu ViCa
  • 5,077
  • 10
  • 43
  • 93

1 Answers1

0

You should add flex:1 to your base container styles for both your list and your item.

...    
entryContainer: {
        flex:1,
        flexDirection: 'row',
        paddingBottom: 20,
        paddingLeft: 20
      },
...


 cartContainer: {
    flex:1,
    flexDirection: 'column', 
  },
Nostromo
  • 959
  • 2
  • 7
  • 25