简体   繁体   English

反应原生卡(原生基础)onPress 不起作用

[英]React native card (native base) onPress doesn't work

I want to display cards with news from a JSON file.我想显示带有来自 JSON 文件的新闻的卡片。 Getting the JSON works fine, but I want to add a onPress event, so I can click the card and navigate to the article.获取 JSON 工作正常,但我想添加一个 onPress 事件,以便我可以单击卡片并导航到文章。

My card view:我的卡片视图:

<Card>
  <CardItem button onPress={this._OnButtonPress(news.id)}>
    <Left>
      <Body>
        <Text style={styles.cardText}>{news.title}</Text>
      </Body>
    </Left>
  </CardItem>
  <CardItem>
    <Left>
        <Icon style={styles.icon} name="chatbubbles" />
        <Text>{news.comments} comments</Text>
    </Left>
    <Right>
      <Text>{news.published}</Text>
    </Right>
  </CardItem>
</Card>

I am trying to pass a variable to the onButtonPress() function我正在尝试将变量传递给 onButtonPress() 函数

_OnButtonPress(newsID) {
  Alert.alert(newsID.toString());
}

To test the onPress event, all I did is alert the parameter.为了测试 onPress 事件,我所做的只是提醒参数。

I don't see anything wrong, but still I got this error我没有发现任何问题,但仍然出现此错误

Does anyone know how I can fix this and what Im doing wrong here.有谁知道我如何解决这个问题以及我在这里做错了什么。 Thanks in advance.提前致谢。

Update更新

My updated class:我更新的课程:

import React, { Component } from "react";
import {
  Image,
  ListView,
  StyleSheet,
  Text,
  View,
  Alert
} from 'react-native';

import {
  Container,
  Header,
  Left,
  Right,
  Button,
  Card,
  CardItem,
  Icon,
  Body,
  Content,
  Logo
} from 'native-base';

import styles from "./styles";

const logo = require("../../../img/f1today.png");

var REQUEST_URL = 'http://v2.first-place.nl/test/news.json';

class News extends Component {
  constructor(props) {
    super(props);

    this._OnButtonPress = this._OnButtonPress.bind(this);

    this.state = {
      dataSource: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
      loaded: false,
    };
  }

  _OnButtonPress(newsID) {
    Alert.alert(newsID.toString());
  }

  componentDidMount() {
    this.fetchData();
  }

  fetchData() {
    fetch(REQUEST_URL)
      .then((response) => response.json())
      .then((responseData) => {
        this.setState({
          dataSource: this.state.dataSource.cloneWithRows(responseData.articles),
          loaded: true,
        });
      })
      .done();
  }

  render() {

    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

    return (
      <Container style={styles.container}>
        <Header
          style={{ backgroundColor: "#fff" }}
          androidStatusBarColor="#f05423"
          iosBarStyle="light-content">

        <Left>
          <Button
            transparent
            onPress={() => this.props.navigation.navigate("DrawerOpen")}
          >
            <Icon name="ios-menu" style={{color: 'black'}} />
          </Button>
        </Left>
        <Body> 
          <Image source={logo} style={styles.headerLogo} />
        </Body>
        <Right />

      </Header>

      <Content padder>

        <ListView
          dataSource={this.state.dataSource}
          renderRow={this.renderNews}
          style={styles.listView}
        />

      </Content>
    </Container>
    );
  }

  renderLoadingView() {
    return (
      <View style={styles.loading}>
        <Text>
          Loading news...
        </Text>
      </View>
    );
  }

  renderNews(news) {
    return (
      <Card>
        <CardItem button onPress={()=> this._OnButtonPress(news.id)}>
          <Left>
            <Body>
              <Text style={styles.cardText}>{news.title}</Text>
            </Body>
          </Left>
        </CardItem>
        <CardItem>
          <Left>
              <Icon style={styles.icon} name="chatbubbles" />
              <Text>{news.comments} comments</Text>
          </Left>
          <Right>
            <Text>{news.published}</Text>
          </Right>
        </CardItem>
      </Card>
    );
  }
}

export default News;

You should wrap your CardItem with TouchableOpacity or any other Touchable item.您应该使用 TouchableOpacity 或任何其他 Touchable 项目包装您的 CardItem。 And give onPress function to that Touchable item.并为该 Touchable 项目提供 onPress 功能。

<TouchableOpacity onPress={() => //your function}
    <CardItem>
    </CardItem>
</TouchableOpacity>

Note: Make sure you use the <TouchableOpacity> component associated with the react-native package rather than the react-native-gesture-handler package.注意:确保使用与react-native包关联的<TouchableOpacity>组件,而不是react-native-gesture-handler包。 Visual Studio Code editor may auto-import from react-native-gesture-handler which does not work in this particular use case. Visual Studio Code 编辑器可能会从react-native-gesture-handler自动导入,这在此特定用例中不起作用。

Correct Package:正确的包装:

import { TouchableOpacity } from 'react-native';

Incorrect Package:错误的包裹:

import { TouchableOpacity } from 'react-native-gesture-handler';

For me i left the button={true} prop off, when i added it works.对我来说,当我添加它时,我离开了 button={true} 道具。 See example below.请参阅下面的示例。

  <CardItem 
       button={true}
       onPress={() => {this.cardSelected(item.name)}}
       style={{paddingTop:0,paddingBottom:0,paddingLeft:0,paddingRight:0}}>
      <Image  source={item.img} style={{flex:1,resizeMode: 'cover',height: 175}} />
      <Text style={styles.cardheading}>{item.name}</Text>
        <Image source={cardline} style={styles.cardline}/>
        <Text style={styles.cardtext}> {item.text}</Text>

      </CardItem>

You need to bind this function.你需要绑定这个函数。 Write the following code inside your constructor function:在构造函数中编写以下代码:

this._OnButtonPress = this._OnButtonPress.bind(this);

Also, changed the onPress as following:此外,将 onPress 更改为如下:

onPress={()=> this._OnButtonPress(news.title)}

Finally, i could see the onPress been written on the component.最后,我可以看到 onPress 写在组件上。 Rather you should define/write it inside that container.相反,您应该在该容器内定义/编写它。

The problem you are having is that the method cannot access the scope of the view.您遇到的问题是该方法无法访问视图的范围。 Right now you have your renderNews method defined this way:现在你的 renderNews 方法是这样定义的:

renderNews(news) { }

If you declare your method this way you will not have this available on your method and as "this" is undefined, all the methods will trigger an error because you are trying to access to "undefined.methodName()".如果您以这种方式声明您的方法,您将无法在您的方法中使用 this,并且由于“this”未定义,所有方法都会触发错误,因为您正在尝试访问“undefined.methodName()”。 Having said that, you should "tie" the context to your method declaring it this way:话虽如此,您应该将上下文“绑定”到您的方法中,以这种方式声明它:

renderNews = (news) => { }

Now you have the context attached to the method and "this" is accesible inside.现在您已将上下文附加到该方法,并且“this”在内部是可访问的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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