我有一个名为AuditionItem的组件,该组件的多个实例被添加到了名为AuditionsList的父组件中。
我已完成导出默认的connect(mapStateToProps)(AuditionItem)
根据我的经验,仅对一个AuditionItem实例(启动状态更改的一个实例)调用mapStateToProps。但我希望为AuditionItem的每个实例调用mapStateToProps。
有没有办法做到这一点?
这是我的AuditionItem.js代码:
false
以及父AuditionsList.js的代码
import React from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import Moment from 'moment';
import colors from './../styles/colors';
import { store } from './../App';
import { addBookmark, removeBookmark } from './../actions/creators';
import { connect } from 'react-redux';
class AuditionItem extends React.Component {
_toggleBookmark = (auditionId, bookmarked) => {
if(bookmarked)
store.dispatch(removeBookmark(auditionId));
else
store.dispatch(addBookmark(auditionId));
}
render() {
Moment.locale('en');
let bookmarked = (this.props.auditions.indexOf(this.props.auditionId) > -1) ? true : false;
let roleString = String(this.props.role);
if(roleString.length > 35)
roleString = roleString.substring(0, 35) + " ...";
let projectString = String("Project: (" + this.props.productionType + ") " + this.props.project);
if(projectString.length > 35)
projectString = projectString.substring(0, 35) + " ...";
let productionHouseString = String("Production House: " + this.props.productionHouse);
if(productionHouseString.length > 35)
productionHouseString = productionHouseString.substring(0, 35) + " ...";
let iconName = `ios-bookmark${bookmarked ? '' : '-outline'}`;
return (
<View style={styles.auditionItemWithBookmark}>
<View style={styles.bookmark}>
<TouchableOpacity onPress={() => this._toggleBookmark(this.props.auditionId, bookmarked)} >
<Ionicons name={iconName} size={25} />
</TouchableOpacity>
</View>
<View style={styles.auditionItem}>
<Text style={styles.role}>{roleString}</Text>
<Text style={styles.project}>{projectString}</Text>
<Text style={styles.productionHouse}>{productionHouseString}</Text>
<Text style={styles.auditionDate}>Begins: {Moment(String(this.props.auditionDate).replace('"','').replace('"', '')).format('LLLL')}</Text>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
auditionItemWithBookmark: {
flex: 1,
flexDirection: "row",
backgroundColor: colors.auditionItemBackgroundColor,
borderRadius: 10,
margin: 10,
padding: 15,
},
bookmark: {
flex: 1,
paddingTop: 5,
},
auditionItem: {
flex: 8,
flexDirection: "column",
backgroundColor: colors.auditionItemBackgroundColor,
},
role: { color: colors.auditionItemColor, fontSize: 20, fontWeight: "bold" },
project: { color: colors.auditionItemColor },
productionHouse: { color: colors.auditionItemColor },
auditionDate: { color: colors.auditionItemColor },
});
const mapStateToProps = state => {
return {
auditons: state.bookmarks.auditions,
}
}
export default connect(mapStateToProps)(AuditionItem);
App.js代码:
import React from 'react';
import { Text, View, FlatList, ActivityIndicator } from 'react-native';
import { connect } from 'react-redux';
import AuditionItem from './AuditionItem';
import Auditions from './../data/Auditions';
import { store } from './../App';
class AuditionsList extends React.Component {
constructor(props) {
super(props);
this.state = { isLoading: true, data: [] }
}
componentDidMount() {
this._refreshData();
}
componentDidUpdate(prevProps) {
if((this.props.location !== prevProps.location) || (this.props.roleType !== prevProps.roleType))
this._refreshData();
}
_onRefresh() {
this.setState({ isLoading: true }, this._refreshData() );
}
_refreshData = () => {
Auditions.fetchAuditions(this.props.productionType, this.props.location, this.props.roleType).then(auditions => {
this.setState({ isLoading: false, data: this._addKeysToAuditions(auditions) });
});
}
_addKeysToAuditions = auditions => {
return auditions.map(audition => {
return Object.assign(audition, { key: audition.Role});
});
}
_renderItem = ({ item }) => {
return (
<AuditionItem
auditionId={item.objectId}
role={item.Role}
project={item.Project.Name}
productionType={item.Project.ProductionType.Type}
auditionDate={JSON.stringify(item.Date.iso)}
productionHouse={item.Project.ProductionHouse.Name}
auditions={store.getState().bookmarks.auditions}
/>
);
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={{ flex: 1 }}>
<FlatList onRefresh={() => this._onRefresh()} refreshing={this.state.isLoading} data={this.state.data} renderItem={this._renderItem} />
</View>
);
}
}
const mapStateToProps = state => {
return {
location: state.settings.location,
roleType: state.settings.roleType,
};
}
export default connect(mapStateToProps)(AuditionsList);
答案 0 :(得分:1)
这不会创建类的实例,它只会导出类/对象。
export default connect(mapStateToProps)(AuditionItem)
在调用类的构造函数时会得到实例,但这是在导入实例之后。因此,基本上,每次您在内部使用导入的AuditionItem(即
我想问题可能出在AuditionItem
本身,或者是您要传递给的道具。
有关
mapStateToProps
的其他信息 来自official Redux文档[mapStateToProps(state,[ownProps]):stateProps](函数):如果指定了此参数,则新组件将订阅Redux存储更新。这意味着每当商店更新时,都会调用mapStateToProps。 mapStateToProps的结果必须是一个普通对象,该对象将合并到组件的props中。如果您不想订阅商店更新,请传递null或undefined代替mapStateToProps。