Robert Templeton
Robert Templeton

Reputation: 149

React native Modal not showing up unless I make a change and save my code

I am working on a goods-in app for a handheld device built in react native. Whenever a product is scanned using the barcode scanner I want to set it as selected and then have that products details pop up in a modal for the user. The problem I'm having is the modal is not popping up but the existing details are disappearing and if I make a change to the Modals props and then save it the page reloads and the Modal appears.

Another thing that I find strange is if I remove the <Modal> and just have it switch to a <View> It works no problem.

const OrderLineItem = ({item, finishEditingInQty}) => {

const {selected} = item

if(selected){
    console.log("Item selected")
    return (
        <Modal
            style={styles.centeredView}
            animationType="slide"
            transparent={true}
            visible={true}
        >
            <View style={styles.modalLineItemContainer}>
                <View style={styles.modalLineItem}>
                    <Text>SELECTED</Text>
                </View>
                <View style={styles.modalLineItem}>
                    <Text>{item.sageStockInfo.Barcode}</Text>
                </View>
                <Pressable
                    onPress={() => {
                        finishEditingInQty(item.LineID)
                    }}
                    style={({ pressed }) => [
                        {
                            backgroundColor: pressed
                            ? 'rgb(210, 230, 255)'
                            : 'white'
                        },
                        styles.orderListItem
                ]}>
                    <Text>Done</Text>
                </Pressable>
            </View>
        </Modal>
    )
} else {
    return (
        <View style={styles.lineItemContainer}>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>{item.ProductCode} - {item.ProductDescription}</Text>
            </View>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>Outstanding: {item.Quantity}</Text>
                <Text style={styles.lineItemText}>In Qty: {item.inQty}</Text>
            </View>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>Warehouse: {item.Warehouse}</Text>
            </View>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>{item.sageStockInfo.Barcode}</Text>
            </View>
        </View>
    )
}

}

Upvotes: 0

Views: 4947

Answers (3)

Doug Watkins
Doug Watkins

Reputation: 1448

You are using Modal in a very strange way. When I want a modal, in code very similar to this, I do the following.

<View>
  <Modal
    visible={selected}
    ....
  >
    ...Modal content
  </Modal>
  ...other content displayed while modal is not up
</View>

If the modal is visible, it covers everything else - its a modal and that's what it should do. No need to have logic determining which view to show. If you were going to go down that road, because it makes more sense to you or whatever, then don't use a modal - those are specifically for displaying a modal screen over the currently displayed screen - just use a view like you mentioned.

Hopefully that helps.

Upvotes: 1

Robert Templeton
Robert Templeton

Reputation: 149

So I managed to get this working but still don't fully understand why. I wrapped the modal in a view and then added a height to view and only then and with the height added does it work. If I remove the styles from the View it goes back to not working.

const OrderLineItem = ({item, finishEditingInQty}) => {

const [selected, setSelected] = useState(false)

useEffect(() => {
    setSelected(item.selected)
})

if(selected){
    console.log("Item selected")
    return (
        <View style={styles.modalContainer}>
        <Modal
            style={styles.centeredView}
            animationType="slide"
            transparent={true}
            visible={selected}
        >
            <View style={styles.modalLineItemContainer}>
                <View style={styles.modalLineItem}>
                    <Text>SELECTED</Text>
                </View>
                <View style={styles.modalLineItem}>
                    <Text>{item.sageStockInfo.Barcode}</Text>
                </View>
                <Pressable
                    onPress={() => {
                        finishEditingInQty(item.LineID)
                    }}
                    style={({ pressed }) => [
                        {
                            backgroundColor: pressed
                            ? 'rgb(210, 230, 255)'
                            : 'white'
                        },
                        styles.orderListItem
                ]}>
                    <Text>Done</Text>
                </Pressable>
            </View>
        </Modal>
        </View>
    )
} else {
    return (
        <View style={styles.lineItemContainer}>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>{item.ProductCode} - {item.ProductDescription}</Text>
            </View>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>Outstanding: {item.Quantity}</Text>
                <Text style={styles.lineItemText}>In Qty: {item.inQty}</Text>
            </View>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>Warehouse: {item.Warehouse}</Text>
            </View>
            <View style={styles.lineItem}>
                <Text style={styles.lineItemText}>{item.sageStockInfo.Barcode}</Text>
            </View>
        </View>
    )
}

}

const styles = StyleSheet.create({ lineItemContainer: { borderWidth: 3, borderColor: "blue"

},
lineItem: {
    backgroundColor: "red"
},
lineItemText: {
    fontSize: 22
},
modalContainer: {
    height: 5

},
centeredView: {
    justifyContent: "center",
    flex: 1
},
modalLineItemContainer: {
    justifyContent: "center",
    alignItems: "center",
    flex: 1,
    borderWidth: 1,
    margin: 20,
    backgroundColor: "red"
}

 

})

export default OrderLineItem;

Upvotes: 0

Jancer Lima
Jancer Lima

Reputation: 954

You need to create useState to re-render your screen when you achieve the requirement to open the modal. For example:

import React, {useState} from 'react'
import {Modal} from 'react-native'

const App = () => {
   const [state, setState] = useState(false)
   return(
      <Modal 
         style={styles.centeredView}
         animationType="slide"
         transparent={true}
         visible={state}
    />
  )
}

When you use setState(true) the Modal will open, setState(false) the Modal will close, so you need you to use setState(true) when the conditions to open the Modal was achieved

Upvotes: 0

Related Questions