Я хочу создать облако тегов, которое позволит людям включать или отключать теги в качестве фильтров для поиска.Я представляю это как вкладку на своей странице результатов (я использую потоковую маршрутизацию, если это уместно).
Я использую пользовательский компонент с именем ToggleButton, который переключается между включенным / отключенным состоянием путем измененияcolor.
В моем контейнере я передаю функцию обратного вызова кнопке, как это:
onStateChangeCallback = (newState, buttonId) => {
console.log("container " + newState + " " + buttonId);
}
render = () => {
const { Layout, tags } = this.props;
return (
<Layout
tags={tags}
onStateChange={this.onStateChangeCallback}
/>
);
}
const mapDispatchToProps = {
toggleTag,
};
const mapStateToProps = state => ({
tags: state.tagfilterreducer.tags || [],
});
Компонент Layout выглядит так:
const RecipeTagFilterComponent = ({tags, onStateChange}) => {
return (
<Container>
<FlatList
numColumns={2}
data={tags}
renderItem={({ item }) => (
<ToggleButton textValue={item.name} onStateChange={onStateChange} buttonId={item.id} />
)}
/>
</Container>
);
}
Класс ToggleButton выглядит следующим образом:
export default class ToggleButton extends Component {
constructor(props) {
super(props)
}
state = {
}
render() {
return (
<View style={styles.container}>
<SimpleToggleButton textValue={this.props.textValue} onStateChange={this.props.onStateChange} buttonId={this.props.buttonId} />
</View>
);
}
}
Наконец, SimpleToggleButton выглядит следующим образом:
class SimpleToggleButton extends Component {
state = {
toggle: false,
}
_onPress() {
const newState = !this.state.toggle;
this.setState({toggle:newState});
this.props.onStateChange && this.props.onStateChange(newState, this.props.buttonId);
}
render() {
const {toggle} = this.state;
const buttonTextColor = toggle ? "white" : "black";
const buttonBackground = toggle ? "dodgerblue" : "#BDBDBD";
return (
<View style={{flexDirection: 'row'}}>
<TouchableOpacity
onPress={() => this._onPress()}
style={{margin:10, flex: 1, height: 60, backgroundColor: buttonBackground, justifyContent:'center', borderRadius: 30}}
>
<Text style={{color:buttonTextColor , backgroundColor: 'transparent', textAlign: 'center', fontSize:16}}>{this.props.textValue}</Text>
</TouchableOpacity>
</View>
);
}
}
Мой обратный вызов выполняется правильно, когда я нажимаю кнопку.
Как я могу изменить свой mapDispatchToProps
, чтобы при нажатии кнопки выполнялось действие, называемое TOGGLE_FILTER_TAG
?
=========== РЕДАКТИРОВАТЬ - РЕШЕНИЕ ============
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
class FilterListingContainer extends Component {
static propTypes = {
Layout: PropTypes.func.isRequired,
tags: PropTypes.arrayOf(PropTypes.shape()).isRequired,
}
render = () => {
const { Layout, tags } = this.props;
return (
<Layout
tags={tags}
onStateChange={this.props.clickHandler} // clickHandler prop is defined in mapDispatchToProps
/>
);
}
}
const mapStateToProps = state => ({
tags: state.tagfilterreducer.tags || [],
});
function mapDispatchToProps(dispatch) {
return {
clickHandler: (newState, buttonId) => {
dispatch({
type: 'TOGGLE_FILTER_TAG',
data: buttonId,
})
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(FilterListingContainer);