【问题标题】:Convert expansion panel functional component to Class Component将扩展面板功能组件转换为类组件
【发布时间】:2019-08-27 07:23:21
【问题描述】:

我对反应比较陌生。我一直在尝试为下面的手风琴扩展面板创建一个功能格式的类组件。我无法根据类组件更改 handleChange 事件。我已经尝试了所有可能的方法,但我失败了。

 import React from 'react';
 import { makeStyles } from '@material-ui/core/styles';
 import ExpansionPanel from '@material-ui/core/ExpansionPanel';
 import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';
 import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';
 import ExpandMoreIcon from '@material-ui/icons/ExpandMore';

 const useStyles = makeStyles(theme => ({

 }));

 export default function ControlledExpansionPanels() {


 const classes = useStyles();

 const [expanded, setExpanded] = React.useState(false);


 const handleChange = panel => (event, isExpanded) => {
 setExpanded(isExpanded ? panel : false);
 };


  return (

  <div className={classes.root}>

  <ExpansionPanel expanded={expanded === 'panel1'} onChange={handleChange('panel1')}>

   <ExpansionPanelSummary
      expandIcon={<ExpandMoreIcon />}
      aria-controls="panel1bh-content"
      id="panel1bh-header"
    >


    </ExpansionPanelSummary>
    <ExpansionPanelDetails>

    </ExpansionPanelDetails>
  </ExpansionPanel>
  <ExpansionPanel expanded={expanded === 'panel2'} onChange={handleChange('panel2')}>
    <ExpansionPanelSummary
      expandIcon={<ExpandMoreIcon />}
      aria-controls="panel2bh-content"
      id="panel2bh-header"
    >

    </ExpansionPanelSummary>
    <ExpansionPanelDetails>

    </ExpansionPanelDetails>
  </ExpansionPanel>


</div>

);

}

请帮忙!

【问题讨论】:

  • useStyles 是你的自定义钩子吗?
  • @AtinSingh 我相信这是来自material ui => material-ui.com/styles/api的钩子
  • 好的,让我检查一下
  • @DamianBusz 刚刚检查过了。钩子是在主组件外部声明的,因此保持其他代码不变,我们可以将类 const 转移到 render 中。但是我还是不明白你为什么要把这个功能组件转换成类
  • @AtinSingh 这是一个很好的问题,我个人会把它作为功能组件。

标签: reactjs event-handling material-ui react-state


【解决方案1】:

会是这样的

 export default class ControlledExpansionPanels extends React.Component {


 // const classes = useStyles();// // you can't use custom hook in class Component //

 const [expanded, setExpanded] = React.useState(false); // previous hook now not needed //

 state = { expanded: false }




handleChange = panel => (event, isExpanded) => {
 // setExpanded(isExpanded ? panel : false); // //previous state manager , now not needed //
 isExpanded ? this.setState({ expanded: panel}) : this.setState({ expanded: false }) //new state manager//
 };

render() {
  return (

  <div className={classes.root}>

  <ExpansionPanel expanded={this.state.expanded === 'panel1'} onChange={this.handleChange('panel1')}>

   <ExpansionPanelSummary
      expandIcon={<ExpandMoreIcon />}
      aria-controls="panel1bh-content"
      id="panel1bh-header"
    >


    </ExpansionPanelSummary>
    <ExpansionPanelDetails>

    </ExpansionPanelDetails>
  </ExpansionPanel>
  <ExpansionPanel expanded={this.state.expanded === 'panel2'} onChange={this.handleChange('panel2')}>
    <ExpansionPanelSummary
      expandIcon={<ExpandMoreIcon />}
      aria-controls="panel2bh-content"
      id="panel2bh-header"
    >

    </ExpansionPanelSummary>
    <ExpansionPanelDetails>

    </ExpansionPanelDetails>
  </ExpansionPanel>


</div> 
)}

我认为这应该可行.. 除了你自己的钩子一切都很好。

【讨论】:

  • 如果 useStyle 不是您的自定义钩子,那么您可以在返回之前声明 const 内部渲染,如@Damian 的回答中所示
  • 抛出错误:'expanded' is not defined no-undef in line 跨度>
  • 哦,是的,我的错,扩展的道具应该是expanded={this.state.expanded === "panel1"} panel2 one
  • 对其进行了编辑。同时,如果你想重构它,你可以在通过const { expanded } = this.state 返回内部渲染函数之前解构你的状态
  • @trek 没问题。干杯!!
【解决方案2】:

如果您没有正确描述或交付整个代码,很难说您有什么问题,我确实将您的功能组件写入类组件,但我无法真正检查它是否有效或者handleChange是否有任何问题。请检查并告诉我问题出在哪里,是否解决了您的问题。

export default class ControlledExpansionPanels extends Component {
    constructor(props){
        super(props)
        this.state = {expanded: false}
    }

    handleChange =  panel => (event, isExpanded) =>{
    if(isExpanded) {
        this.setState({expanded: panel})
    } else {
        this.setState({expanded: false})
    }

    }
    render() {
        const classes = useStyles();
        return (
            <div className={classes.root}>
            <ExpansionPanel
              expanded={this.state.expanded === "panel1"}
              onChange={() => this.handleChange("panel1")}
            >
              <ExpansionPanelSummary
                expandIcon={<ExpandMoreIcon />}
                aria-controls="panel1bh-content"
                id="panel1bh-header"
              ></ExpansionPanelSummary>
              <ExpansionPanelDetails></ExpansionPanelDetails>
            </ExpansionPanel>
            <ExpansionPanel
              expanded={this.state.expanded === "panel2"}
              onChange={() => this.handleChange("panel2")}
            >
              <ExpansionPanelSummary
                expandIcon={<ExpandMoreIcon />}
                aria-controls="panel2bh-content"
                id="panel2bh-header"
              ></ExpansionPanelSummary>
              <ExpansionPanelDetails></ExpansionPanelDetails>
            </ExpansionPanel>
          </div>
        )
    }
}

【讨论】:

  • 没错,我的错。我忘了在前面添加 this.state,因为它是类组件状态的一部分。我猜太习惯了钩子:) 编辑了帖子中的代码,现在应该很好
  • 这在将 expand={expanded==='panel1'} 更改为 expand={this.state.expanded==='panel1'} 后有效。谢谢!
  • @trek 欢迎您。如果这是正确答案,请将其标记为正确答案,以供遇到类似问题并可能找到您的主题的人使用。谢谢
【解决方案3】:
import React from 'react';

export default class ControlledExpansionPanels extends Component {
constructor(props){
    super(props)
    this.state = {expanded: false}
}

handleChange =  panel => (event, expanded) =>{
if(expanded) {
    this.setState({expanded: panel})
} else {
    this.setState({expanded: false})
}

}
render() {
    return (
        <div>
        <ExpansionPanel
          expanded={this.state.expanded === "panel1"}
          onChange={this.handleChange("panel1")}
        >
          <ExpansionPanelSummary
            expandIcon={<ExpandMoreIcon />}
            aria-controls="panel1bh-content"
            id="panel1bh-header"
          ></ExpansionPanelSummary>
          <ExpansionPanelDetails></ExpansionPanelDetails>
        </ExpansionPanel>
        <ExpansionPanel
          expanded={this.state.expanded === "panel2"}
          onChange={this.handleChange("panel2")}
        >
          <ExpansionPanelSummary
            expandIcon={<ExpandMoreIcon />}
            aria-controls="panel2bh-content"
            id="panel2bh-header"
          ></ExpansionPanelSummary>
          <ExpansionPanelDetails></ExpansionPanelDetails>
        </ExpansionPanel>
      </div>
    )
}}

【讨论】:

  • Sanchari,感谢您的回答!也许您可以编辑您的答案,以便更清楚地说明您的代码示例与问题示例的不同之处以及它如何解决问题?这比扫描整个代码更容易发现主要变化。
猜你喜欢
  • 2020-02-08
  • 2020-08-26
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多