_this2.onPressed не является функцией - PullRequest
0 голосов
/ 03 июля 2019

Когда я нажимаю TouchableOpacity внутри метода renderItem, я получаю сообщение об ошибке «_this2.onPressed не является функцией».

Я нашел документацию о передаче функций компоненту (ссылка приведена ниже): https://reactjs.org/docs/faq-functions.html

Я пробовал эти решения, но они не работали.Как мне решить эту проблему?Я новичок в React Native.

import React, { Component } from 'react';
import { Text, FlatList,View, StyleSheet, TouchableOpacity, Image} from 'react-native';
import { connect } from 'react-redux';
import {fetchPosts,likePost} from '../../actions'
import {Card} from '../Card';
import Icon from 'react-native-vector-icons/FontAwesome'


class PostScreen2 extends Component {
    constructor(props){
        super(props)
        this.onPressed = this.onPressed.bind(this)
    }

    shouldComponentUpdate(nextProp, nextState){
        console.log("Should component update")
        return true
    }

    componentDidMount(){
        const {id} = this.props
        console.log("ID'miz: ", id)
        this.props.fetchPosts(id)
    }

    componentDidUpdate(){
        console.log("Component did update.")
    }

    onPressed(postID){
        this.props.likePost(postID,this.props.id)
    }

    renderItem({item}){
        return(
            <Card>
                <View style={{flexDirection:'column',position:'absolute', justifyContent:'space-between'}}>
                    <View style={styles.topWrapper}>
                        <View style={styles.imageWrapper}>
                            <Image source={require('../../images/cat.png')}></Image>
                        </View>
                    <View style={styles.infoWrapper}>
                        <Text style={styles.nameWrapper}>{item.author_name}</Text>
                        <Text style={{fontSize:14}}>{item.date}</Text>
                    </View>
                </View>
                <View style={styles.contentWrapper}>
                    <Text style={{fontSize:20}}>{item.content}</Text>
                </View>
                    <View styles={styles.likeWrapper}>
                        <Text style={{marginLeft:10, fontSize:18, fontWeight:'bold'}}>{item.likes} likes</Text>
                    </View>
                    <TouchableOpacity onPress={() => {this.onPressed(item.id)}}>
                        <Icon style={{marginLeft:10}} size={25} name='star-o' />
                    </TouchableOpacity>
                </View>
            </Card>         
        )        
    }

    render() {
        const {posts} = this.props
        return (
            <FlatList
            data={posts}
            renderItem={this.renderItem}
        />
        );
    }
}


const mapStateToProps = state => {
    var posts = []
    for (var property in state.posts.data) {
      posts = state.posts.data[property]
    }

    return {
        posts,
        id: state.id
    }
}

const styles = StyleSheet.create({
    titleWrapper:{
        fontSize: 16,
        color: 'black'
    },
    authorWrapper: {
        fontSize: 14,
        color: 'gray'
    },
    descriptionWrapper: {
        marginLeft: 10,
        marginRight: 10,
        fontSize: 13,
        color: 'gray'
    },
    imageWrapper: {
        marginLeft: 10,
        marginTop: 10
    },
    nameWrapper: {
      fontWeight: 'bold',
      fontSize: 20
    },
    infoWrapper:{
      marginLeft: 10,
      marginTop: 10
    },
    topWrapper:{
      flex: 1,
      flexDirection: 'row'
    },
    contentWrapper: {
      marginLeft: 10,
      marginRight: 10,
    },
    likeWrapper: {
      fontSize: 18,
      fontWeight: 'bold'
    }
})


export default connect(mapStateToProps, {fetchPosts,likePost})(PostScreen2);

Ответы [ 3 ]

0 голосов
/ 03 июля 2019

похоже, что вы новичок в javascript. То, как вы объявили (или пытались объявить) onPressed и функцию renderItem, неверно. Используйте этот код вместо этого в вашем классе:

onPressed = (postID) => {
  this.props.likePost(postID,this.props.id)
}
renderItem = ({item}) => {
    return(
        <Card>
            <View style={{flexDirection:'column',position:'absolute', justifyContent:'space-between'}}>
                <View style={styles.topWrapper}>
                    <View style={styles.imageWrapper}>
                        <Image source={require('../../images/cat.png')}></Image>
                    </View>
                <View style={styles.infoWrapper}>
                    <Text style={styles.nameWrapper}>{item.author_name}</Text>
                    <Text style={{fontSize:14}}>{item.date}</Text>
                </View>
            </View>
            <View style={styles.contentWrapper}>
                <Text style={{fontSize:20}}>{item.content}</Text>
            </View>
                <View styles={styles.likeWrapper}>
                    <Text style={{marginLeft:10, fontSize:18, fontWeight:'bold'}}>{item.likes} likes</Text>
                </View>
                <TouchableOpacity onPress={() => {this.onPressed(item.id)}}>
                    <Icon style={{marginLeft:10}} size={25} name='star-o' />
                </TouchableOpacity>
            </View>
        </Card>         
    )        
}
0 голосов
/ 03 июля 2019

У вас уже есть ответ, но, чтобы уточнить немного.

Чтобы решить эту проблему, вы должны понять, как вы используете обратные вызовы в Javascript и каков контекст (это).

React вызывает методы обратного вызова в другом контексте, и у вас есть два варианта.

  • Свяжите свою функцию с этим;
  • Используйте функции стрелок, которые разделяют контекст (это). Таким образом, вам не нужно связывать их с вашим контекстом.
export default class App extends React.Component {
  onPress() {
    // Not your this so you do not have access to your class
    // In order to bind this function you can put ``this.onPress = this.onPress.bind(this)` on class constructor.
  }

  arrowOnPress = () => {
    // Your class this
    this.onPress();
  };

  render() {
    return (
      <View>
        <Button onPress={this.onPress} title="I am not binded" />
        <Button onPress={this.arrowOnPress} title="I am binded" />
      </View>
    );
  }
}

Надеюсь, это поможет

0 голосов
/ 03 июля 2019

Можете ли вы изменить метод рендеринга на следующий?

    ...
    renderItem =({item}) => {
            return(
                <Card>
                    ...
                    ...
                </Card>         
            )        
    }
    ...

Я думаю, вам нужно связать метод рендеринга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...