0

Im trying to pass parameters through to a component two levels deep. I have 2 screens (MainScreen & UserProfileScreen) with a flat list on both screens, both flat lists use the same component EventCard in its renderItem. EventCard is made up of 3 three nested components EventCardHeader,EventCardBody & EventCardFooter. How do I pass certain arguements only from the UserProfileScreen? I have posted code below to give a better understanding of what I have.

MainScreen

 <FlatList
                data={this.state.events}
                // Get the item data by referencing as a new function to it
                renderItem={({item}) =>
                    <EventCard
                        openEventDetail={() => this.openEventDetail(item)}
                        {...item}
                    />}
            />

UserProfileScreen

   <FlatList
                data={this.state.events}
                // Get the item data by referencing as a new function to it
                renderItem={({item}) =>
                    <EventCard
                        openEventDetail={() => this.openEventDetail(item)}
                        openEditEvent={() => this.openEditEvent(item)}
                        openDeleteEventAlert={() => this.openDeleteEventAlert(item)}
                        {...item}
                    />}
            />



openEditEvent = (event) => {
    this.props.navigation.navigate('EventFormScreen', {
        event: event,
        eventKey: this.state.eventKey,
        editMode: true,
    });
};

EventCard

export default class EventCard extends Component {


render() {

    return (
        <Card>

            <EventCardHeader
                eventOrganiserImage={this.props.eventOrganiserImage}
                eventVenue={this.props.eventVenue}
                openEditEvent={() => this.openEditEvent()}
            />

            <EventCardBody
                openEventDetail={() => this.props.openEventDetail()}
                imageDownloadUrl={this.props.imageDownloadUrl}
            />

            <EventCardFooter
                openEventDetail={() => this.props.openEventDetail()}
                eventName={this.props.eventName}
                eventStartDate={this.props.eventStartDate}
                eventVenue={this.props.eventVenue}
                eventAddressLine1={this.props.eventAddressLine1}
                eventAddressLine2={this.props.eventAddressLine2}
            />

        </Card>
    );
}
};

EvenCardHeader

export default class EventCardHeader extends Component {


render() {

    return (

        <CardSection style={styles.eventCardHeader}>

            <Thumbnail small
                       style={styles.eventOrganiserImage}
                       source={{uri: this.props.eventOrganiserImage}}/>

            <Text style={styles.eventPromoterName}>{this.props.eventVenue}</Text>


            {!!this.props.openEditEvent &&
            <Button onPress={() => this.props.openEditEvent()}>
                Edit
            </Button>
            }

            {!!this.props.openDeleteEventAlert &&
            <Button onPress={() => this.props.openDeleteEventAlert()}>
            Delete
            </Button>
            }

        </CardSection>
    );

}

}

I can see that because I have hardcoded the this.openEditEvent() function into my EventCard component that what's causing me the problem, because then the if statement in EventCardHeader that checks if the this.openEditEvent() exists always evaluates to true. Would someone be able to help show me the right way to do this? Thanks in advance for any help.

UPDATE:

Added in openEditEvent

Andrew Irwin
  • 691
  • 12
  • 40

1 Answers1

0

Where is openEditEvent() declared? It should be in the parent component and passed as props to whatever children you need it in. You can continue to pass it as props from children to children.

EDIT:

Ok so you can pass openEditEvent as props like so:

                <EventCard
                    openEditEvent = this.openEditEvent
                    openEventDetail={() => this.openEventDetail(item)}
                    openDeleteEventAlert={() => this.openDeleteEventAlert(item)}
                    {...item}
                />}

That function can be available in EventCard, and can then be passed AGAIN as props to another child component:

render() {

  var openEditEvent = this.props.openEditEvent;

  return (
    <Card>

        <EventCardHeader
            eventOrganiserImage={this.props.eventOrganiserImage}
            eventVenue={this.props.eventVenue}
            openEditEvent = openEditEvent
        />

        <EventCardBody
            openEventDetail={() => this.props.openEventDetail()}
            imageDownloadUrl={this.props.imageDownloadUrl}
        />

        <EventCardFooter
            openEventDetail={() => this.props.openEventDetail()}
            eventName={this.props.eventName}
            eventStartDate={this.props.eventStartDate}
            eventVenue={this.props.eventVenue}
            eventAddressLine1={this.props.eventAddressLine1}
            eventAddressLine2={this.props.eventAddressLine2}
        />

    </Card>
  );
}
mediaguru
  • 1,807
  • 18
  • 24
  • Thanks for your response, `openEditEvent()` is declared in `UserProfileScreen` Im not sure how to pass it through to the EventCardHeader component nested in Event Card. – Andrew Irwin Dec 20 '18 at 22:04