我有两个组件1)Accordion组件和2)MyCustom组件
现在我将Accordion Component导入到MyCustom Component中,如下所示
import { Accordion } from '../../../controls/accordion';
public clickEvent = () =>{
this.setState({
attachmentsAccordionCollapsed:!this.state.attachmentsAccordionCollapsed
});}
<Accordion title="Attachments" defaultCollapsed={this.state.attachmentsAccordionCollapsed} className={styles.itemCell} ></Accordion>
现在我正在改变状态attachmentsaccordioncollapse的值在改变事件在MyCustom组件,但属性"defaultCollapsed"Accordion组件的值不会随着MyCustom组件状态的改变而改变或更新。
手风琴组件
import * as React from 'react';
import styles from './Accordion.module.scss';
import { IAccordionProps, IAccordionState } from './index';
import { css } from "@uifabric/utilities/lib/css";
import { DefaultButton, IIconProps } from 'office-ui-fabric-react';
/**
* Icon styles. Feel free to change them
*/
const collapsedIcon: IIconProps = { iconName: 'ChevronRight', className: styles.accordionChevron };
const expandedIcon: IIconProps = { iconName: 'ChevronDown', className: styles.accordionChevron };
export class Accordion extends React.Component<IAccordionProps, IAccordionState> {
private _drawerDiv: HTMLDivElement = undefined;
constructor(props: IAccordionProps) {
super(props);
this.state = {
expanded: props.defaultCollapsed == null ? false : !props.defaultCollapsed
};
}
public componentDidUpdate(prevProps) {
this.state = {
expanded: this.props.defaultCollapsed == null ? false : !this.props.defaultCollapsed
};
}
public render(): React.ReactElement<IAccordionProps> {
return (
<div className={css(styles.accordion, this.props.className)}>
<DefaultButton
toggle
checked={this.state.expanded}
text={this.props.title}
iconProps={this.state.expanded ? expandedIcon : collapsedIcon}
onClick={() => {
this.setState({
expanded: !this.state.expanded
});
}}
aria-expanded={this.state.expanded}
aria-controls={this._drawerDiv && this._drawerDiv.id}
/>
{this.state.expanded &&
<div className={styles.drawer} ref={(el) => { this._drawerDiv = el; }}>
{this.props.children}
</div>
}
</div>
);
}
}
不复制props. defaultcollapse到否定的props。我建议不要在accordion中使用本地状态,而只是像其他受控组件一样通过toggle函数从父组件扩展:
class Accordion extends React.Component {
render() {
return (
<div>
Is expanded: {String(this.props.expanded)}
<button onClick={this.props.toggleExpanded}>
toggle expanded
</button>
</div>
);
}
}
class Parent extends React.PureComponent {
state = {
expanded: true,
};
toggleExpanded = () => {
this.setState({ expanded: !this.state.expanded });
};
render() {
return (
<div>
<button onClick={this.toggleExpanded}>
toggle from parent
</button>
<Accordion
expanded={this.state.expanded}
toggleExpanded={this.toggleExpanded}
/>
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>