我正在尝试在页面上显示组件的多个实例。每个实例都应出现在Tab.Pane(语义UI功能)中。但是,在尝试实现这一点时,我遇到了一些奇怪的行为,如下所述。
我有一个组成部分; <MultistepFilterSection />
在此组件中,状态为:
this.state = {
conjunction: "AND" // default
}
此状态由组件中的onClick处理函数修改;
handleConjunctionButtonClick = (conjunction, e) => {
this.setState({conjunction: conjunction})
}
此onClick是通过单击两个按钮之一触发的:
<Button.Group vertical>
<Button
onClick={(e) => this.handleConjunctionButtonClick("AND")}
color={this.state.conjunction === "AND" ? "blue" : null}
>
And
</Button>
<Button
onClick={(e) => this.handleConjunctionButtonClick("OR")}
color={this.state.conjunction === "OR" ? "blue" : null}
>
Or
</Button>
</Button.Group>
我正在使用Semantic UI's Tab component在页面上呈现此组件的3个实例;
const panes = [
{
menuItem: "Panel Data",
render: () =>
<Tab.Pane attached={false}>
<MultistepFilterSection getAudience={this.getAudience} />
</Tab.Pane>
},
{
menuItem: "Geolocation Data",
render: () =>
<Tab.Pane attached={false}>
<MultistepFilterSection getAudience={this.getAudience} />
</Tab.Pane>
},
{
menuItem: "Combined Audience Selection",
render: () =>
<Tab.Pane attached={false}>
<MultistepFilterSection getAudience={this.getAudience} />
</Tab.Pane>
}
]
在render方法中,我有:
<Tab
menu={{ secondary: true, pointing: true }}
panes={panes}
/>
在任意一个选项卡中触发onClick处理程序都会更改组件所有实例中的状态。这正常吗?我认为组件的一个实例中的组件状态是该实例专有的。
在进一步的调查中,我发现当我使用语义UI的Tab组件实例化<MultistepFilterSection />
的多个实例时,便表现出这种行为。当单独渲染实例时,展览的预期行为。
<MultistepFilterSection />
组件的完整代码:
import React from "react";
import { Grid, Button, Container, Icon, Segment } from "semantic-ui-react";
import { connect } from "react-redux";
import uuid from "uuid";
import _ from "lodash";
import RuleGroup from "../rules/RuleGroup";
import { filterGroupCreated, filterGroupDeleted, filterDeleted } from "../../actions/FiltersAction"
export class MultistepFilterSection extends React.Component {
constructor(props) {
super(props);
this.state = {
conjunction: "AND" // default
}
// create one default group
this.props.filterGroupCreated({filterGroupId: uuid()})
this.handleAddRuleGroupButtonClick = this.handleAddRuleGroupButtonClick.bind(this);
this.renderRuleGroups = this.renderRuleGroups.bind(this);
this.handleConjunctionButtonClick.bind(this)
}
handleAddRuleGroupButtonClick() {
// console.log("called handleAddRuleGroupButtonClick()")
const filterGroupId = uuid()
let data = {}
data.filterGroupId = filterGroupId
this.props.filterGroupCreated(data)
}
handleConjunctionButtonClick = (conjunction, e) => {
this.setState({conjunction: conjunction})
}
renderRuleGroups() {
// console.log("called renderRuleGroups()")
return Object.values(this.props.filterGroups).map(function(ruleGroup) {
const key = ruleGroup.id;
// incomplete
let currentGenderSelected
return (
<React.Fragment key={key}>
<RuleGroup
id={key}
key={key}
deleteRuleGroup={this.deleteRuleGroup}
deleteFilter={this.deleteFilter}
currentGenderSelected={currentGenderSelected}
/>
</React.Fragment>
)
}.bind(this))
}
deleteRuleGroup = (id, e) => {
// console.log("delete rule group called")
this.props.filterGroupDeleted({filterGroupId: id})
}
deleteFilter = (filterGroupId, filterId, e) => {
// console.log("deleteFilter() called")
this.props.filterDeleted({
filterGroupId: filterGroupId,
filterId: filterId
})
}
render() {
const isFilterGroupQuery = true
return(
<Grid padded="vertically">
<Grid.Row stretched>
<Grid.Column verticalAlign={"middle"} width={2}>
{_.size(this.props.filterGroups) > 0 &&
<Segment basic>
<Button.Group vertical>
<Button
onClick={(e) => this.handleConjunctionButtonClick("AND")}
color={this.state.conjunction === "AND" ? "blue" : null}
>
And
</Button>
<Button
onClick={(e) => this.handleConjunctionButtonClick("OR")}
color={this.state.conjunction === "OR" ? "blue" : null}
>
Or
</Button>
</Button.Group>
</Segment>
}
</Grid.Column>
<Grid.Column width={14}>
{this.renderRuleGroups()}
</Grid.Column>
</Grid.Row>
<Grid.Row>
<Grid.Column width={2}></Grid.Column>
<Grid.Column width={3}>
<Button
color="grey"
basic
onClick={this.handleAddRuleGroupButtonClick}
>
<Icon name="plus" />Add Rule Group
</Button>
</Grid.Column>
<Grid.Column width={11}>
<Button
color="blue"
onClick={
(isFilterGroupQuery) => this.props.getAudience(
isFilterGroupQuery, this.state.conjunction
)
}
floated={"right"}
>
Run query
</Button>
</Grid.Column>
</Grid.Row>
</Grid>
)
}
}
function mapStateToProps(state) {
return {
filterGroups: state.filters
};
}
export default connect(
mapStateToProps,
{
filterGroupCreated,
filterGroupDeleted,
filterDeleted
}
)(MultistepFilterSection);
答案 0 :(得分:0)
经过大量挖掘,最后在posting an issue上进行了Semantic UI的GitHub回购,我了解到我需要在Tab组件上使用renderActiveOnly={false}
道具。我还必须更改标记,以便窗格对象采用以下格式:
const panes = [
{
key: 1,
menuItem: "Panel Data",
pane: <Tab.Pane><Simple key={1} /></Tab.Pane>
},
{
key: 2,
menuItem: "Geolocation Data",
pane: <Tab.Pane><Simple key={2} /></Tab.Pane>
}
]