如何在另一个组件中调用一个组件的redux动作

时间:2019-05-10 22:48:50

标签: react-native redux

我正在将从API获取的数据渲染到Cards中,我创建了CardContainers组件,该组件映射从API获取的数据,然后在另一个组件中使用该组件。

CardContainers.js

import React from 'react';
import {View} from 'react-native';
import {withNavigation} from 'react-navigation';

class CardContainers extends React.Component{

    addPlace(){
        return this.props.addPlace;
    }
    renderCards(){
        return this.props.data.map((item, index) => {
            return (
                <View key={index}>
                    {this.props.renderCard(item)}
                </View>
            )
        })
    }

    render(){
        return(
            <View>{this.renderCards()}</View>
        )
    }
}

PlacesList.js

import React from 'react';
import ProgressiveInput from 'react-native-progressive-input';
import {StyleSheet, View, Alert, Text, TouchableOpacity, ListView, ScrollView} from 'react-native';
import {Button, Card, Icon} from 'react-native-elements';
import {connect} from 'react-redux';
import CardContainers from './CardContainers';
import * as placesActions from '../redux/actions/placesActions';

const ds = new ListView.DataSource({
    rowHasChanged: (r1, r2) => r1 !== r2,
});


class PlacesList extends React.Component{
    static navigationOptions = ({navigation}) => {
        return {
             title:'Finding new places',
         }
    }

    constructor(props){
        super(props)
        const position = this.props.navigation.getParam('position')
        const tripId = JSON.stringify(this.props.navigation.getParam('tripId')).replace(/\"/g,"");
        const date = JSON.stringify(this.props.navigation.getParam('date')).replace(/\"/g,"");
        this.state={
            position: position,
            tripId: tripId,
            date: date,
            dataSource:ds.cloneWithRows([]),
        }
    }

    renderCard(item){
        return(
            <Card 
                key={item.id}
                title={item.title}
                titleStyle={styles.title}
                containerStyle={{marginTop: 20, marginBottom:20}}
            >
                <View style={{flexDirection: 'row'}}>
                    <Text style={{margin:10}}>
                       Category: {item.category.title}
                    </Text> 
                    <Text style={{margin:10}}>
                       Rating: {item.averageRating}
                    </Text>
                </View>
                <View style ={{flexDirection:'row', alignItems:'center', alignSelf:'center'}}>
                <Button
                icon={<Icon name='add' color='#ffffff'/>}
                buttonStyle={{marginLeft:15, borderRadius:10}}
                title='ADD THIS PLACE'
                type='solid'
                onPress={()=>this.props.addPlace()}
            />
                </View>      
            </Card>
        );
    }

    getPlacesAroundDestination = () => {
        this.props.aroundPlaces(this.state.position);
        this.setState({dataSource: ds.cloneWithRows(this.props.placesAround)})
    }

    autoComplete = async(query) => {
        this.setState({destination: query})
        await this.props.suggestPlaces(this.state.position, query)
        this.setState({dataSource: ds.cloneWithRows(this.props.searchSuggests)})
    }

    inputCleared = () => {
        this.setState({
            destination:'',
            isLoading: false,
            dataSource: ds.cloneWithRows({}),
        });
    }

    onListItemClicked = (searchSuggests) => {
        this.setState({
            title: searchSuggests.title,
            placeId: searchSuggests.id,
            openingHours: searchSuggests.openingHours,
            category: searchSuggests.category,
            position:searchSuggests.position.toString(),
            dataSource:ds.cloneWithRows([]),
        })
    }

    renderRow = (searchSuggests) => {
        return(
            <TouchableOpacity
                style={{padding:10}}
                onPress={()=>this.onListItemClicked(searchSuggests)}
            >
                <Text style={{fontSize:20}}>{searchSuggests.title}</Text>
                <Text style={{fontSize:10}}>{searchSuggests.vicinity}</Text>

            </TouchableOpacity>
        )
    }


    renderSeparator = () => {
        return <View style={{borderWidth:0.5, borderColor:'lightgrey',}}>      </View>
    }

    renderContent(){
        return (
                <CardContainers
                    data={this.props.placesAround.items}
                    renderCard={this.renderCard}
                />
        )
    }

    render(){
        return(
            <View style={styles.container}>

                    <ProgressiveInput
                        style={{marginTop:20, marginLeft:10, marginRight:10}}
                        placeholder='Your destination...'
                        value={this.state.destination}
                        isLoading={this.props.isLoading}
                        onChangeText={this.autoComplete}
                        onInputCleared={this.inputCleared}
                    />

                    <View style={{flex:0}}>
                        <ListView
                            enableEmptySections
                            style={{backgroundColor:'white', margin:20}}
                            dataSource={this.state.dataSource}
                            renderRow={this.renderRow}
                            renderSeparator={this.renderSeparator}
                        />
                    </View>
                    <Button
                        title= 'SUGGEST'
                        style={{alignSelf:'center'}}
                        onPress={() => this.props.aroundPlaces(this.state.position)}
                    />
                <ScrollView>
                    {this.props.placesAround.items? this.renderContent():null}
                </ScrollView>
            </View>
        )
    }
}

const mapStateToProps = (state) => {
    return{
        searchSuggests: state.places.searchSuggests,
        isLoading: state.places.isLoading,
        placesAround: state.places.placesAround,
        geolo: state.location.latitude + ',' + state.location.longitude,
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        addPlace:(tripId, date, title, category, rating, placeID) => dispatch (placesOfPlanActions.addPlace(tripId, date, title, category, rating, placeID)),
        aroundPlaces: (geolo) => dispatch(placesActions.aroundPlaces(geolo)),
        suggestPlaces: (geolo, destination) => dispatch(placesActions.suggestPlaces(geolo, destination))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(PlacesList);

您可以在下面的代码中看到,我想调用addPlace()函数,它是呈现的每个Card的onPress事件中的一个redux动作,但是我不能这样做,因为CardContainers里面没有该函数。那么我有什么办法可以做到呢?我对react-native和redux还是很陌生,仅花了4个月的时间,但我认为我并不完全理解。

1 个答案:

答案 0 :(得分:0)

是的,只需将df HOC添加到random_data,您应该能够像在connect中那样在CardContainers中设置功能。<​​/ p>