如何在更新父组件状态时更新子组件状态

时间:2021-01-31 17:26:30

标签: reactjs react-redux

我有两个组件 1) Accordion 组件和 2) MyCustom 组件

现在我将手风琴组件导入到 MyCustom 组件中,如下所示

import { Accordion } from '../../../controls/accordion';

public clickEvent = () =>{
this.setState({
  attachmentsAccordionCollapsed:!this.state.attachmentsAccordionCollapsed
});}

<Accordion title="Attachments" defaultCollapsed={this.state.attachmentsAccordionCollapsed} className={styles.itemCell} ></Accordion>

现在我正在更改 MyCustom 组件中更改事件的状态attachmentsAccordionCollapsed 值,但 Accordion 组件的属性“defaultCollapsed”值在更改 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>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

我建议不要将 props.defaultCollapsed 复制到否定的 props.expanded,而是建议在手风琴中不要有本地状态,而只是像任何其他受控组件一样传递切换函数从父级扩展:

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>