web-dev-qa-db-ja.com

Reactネイティブカード(ネイティブベース)onPressが機能しない

JSONファイルからのニュースが記載されたカードを表示したい。 JSONの取得は正常に機能しますが、onPressイベントを追加したいので、カードをクリックして記事に移動できます。

私のカードビュー:

<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>

OnButtonPress()関数に変数を渡そうとしています

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

OnPressイベントをテストするために、私が行ったのはパラメーターにアラートを出すことだけです。

何も問題はありませんが、それでもこのエラーが発生します

誰かが私がこれを修正する方法と私がここで間違っていることを知っていますか?前もって感謝します。

更新

私の更新されたクラス:

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;
4
abbob1

あなたが抱えている問題は、メソッドがビューのスコープにアクセスできないことです。これで、renderNewsメソッドが次のように定義されました。

renderNews(news) { }

この方法でメソッドを宣言すると、メソッドでこれを使用できなくなり、「this」が未定義であるため、「undefined.methodName()」にアクセスしようとしているため、すべてのメソッドでエラーがトリガーされます。そうは言っても、コンテキストをメソッドに「結び付け」て、次のように宣言する必要があります。

renderNews = (news) => { }

これで、メソッドにコンテキストがアタッチされ、「this」にアクセスできるようになりました。

1
EnriqueDev

CardItemをTouchableOpacityまたはその他のTouchableアイテムでラップする必要があります。そして、そのTouchableアイテムにonPress機能を与えます。

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

私の場合、button = {true}支柱をオフのままにしましたが、追加すると機能します。以下の例を参照してください。

  <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>
1
sonic_ninja

この関数をバインドする必要があります。コンストラクター関数内に次のコードを記述します。

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

また、onPressを次のように変更しました。

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

最後に、onPressがコンポーネントに書き込まれているのを見ることができました。むしろ、そのコンテナ内で定義/書き込む必要があります。

1
Rohan Kangale