简体   繁体   中英

Navigate to another screen from Flat list item getting pressed

I've been using wix/react-native-navigation package to navigate between screens and handling the stack properly.

Moving across screens is pretty straightforward, firing those transitions when a button gets pressed. But the issue comes up when I have a FlatList and I want to push to a new screen when the user taps an item from the list, looks like the navigator props injected at the beginning is lost or in another context than the onPress callback event;

Here is the sample code

class AlertType extends React.PureComponent {
  _onPress = () => {
      this.props.onPressItem(this.props.itemId, this.props.itemName, this.props.itemImageUrl);
  };

  render() {
      return (
          <TouchableOpacity { ...this.props }
              onPress={ this._onPress }
              style={ itemStyle.cardContainer }>

              <View style={ itemStyle.mainContainer }>
                  <View style={{ width: 10 }}/>
                  <Image
                      source={{ uri: NET.HOST + this.props.itemImageUrl }}
                      style={{ width: 45, height: 45 }}
                  />
                  <View style={{ width: 10 }}/>
                  <Text style={ itemStyle.itemText }>{ this.props.itemName }</Text>
              </View>
          </TouchableOpacity>
      );
  }
}

class AlertsScreen extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            alertTypes: null,
        }
    }

    _onAlertTypePressed(typeId: string, typeName: string, imageUrl: string){

        this.props.navigator.push({
            screen: 'prod.screens.AlertsCreator',
            title: 'Alert',
            passProps: {
                alertId: typeId,
                alertName: typeName,
                alertImage: imageUrl
            }
        });
    }

    _renderListItem = ({ item }) => (
        <AlertType
            itemName={ item.titulo }
            itemId={ item.key }
            itemImageUrl={ item.url }
            onPressItem={ this._onAlertTypePressed }
        />
    );

    render() {
        return (
            <View style={ styles.mainContainer }>
                <FlatList
                    data={ this.state.alertTypes }
                    ItemSeparatorComponent={ () => <View style={{ height: 5 }}/> }
                    renderItem={ this._renderListItem }
                />
            </View>
        );
    }

const mapSessionStateToProps = (state, ownProps) => {
    return {
        session: state.session
    };
}
const mapDispatchToProps = (dispatch) => {
    return {
        actions: bindActionCreators(actions, dispatch)
    };
}
export default connect(mapSessionStateToProps, mapDispatchToProps)(AlertsScreen)

This approach produces the next error 在此处输入图片说明

There have to be something I'm missing, I know this.props.navigator is not undefined, but inside on _onAlertTypePressed the navigator prop is undefined.

The problem is that you pass function to component without binding it to the current context.

You should pass:

this._onAlertTypePressed.bind(this);

another approach is binding your functions in the constructor:

constructor(props) {
  this._onAlertTypePressed = this._onAlertTypePressed.bind(this);
}

I've had this happen before also.

I had to declare navigator between the render and return blocks

render() {

const navigator = this.props.navigator
return()}}

then pass navigator through when calling _onAlertTypePressed

() => _onAlertTypePressed(navigator)

then use navigator vs this.props.navigator inside _onAlertTypePressed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM