【问题标题】:React material-ui dynamically adding Expansion Panel on button clickReact material-ui 在按钮单击时动态添加扩展面板
【发布时间】:2019-09-11 19:27:31
【问题描述】:

我正在尝试使用 React Material UI 动态添加扩展面板。它已添加,但我无法展开它(即isExpanded 是真的,即使面板没有展开)。我在 Material UI 版本 4.4.1 和 React.js 版本是 16.9.0。谁能帮我弄清楚为什么它不能按预期工作?

const TransportFlow = () => {
        const [expanded, setExpanded] = React.useState('');
        const [points, setPoints] = React.useState([]);
        const handleChange = panel => (evt, isExpanded) => {
            setExpanded(isExpanded ? panel : false);
        };

        const addPoint = () => {
            const arr = [];
            const pointPanel = (
                <ExpansionPanel key='p1' expanded={expanded === 'panel1'} onChange={handleChange('panel1')}>
                    <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />} id="panel1bh-header" aria-controls="panel1bh-content">
                        Hello
                    </ExpansionPanelSummary>
                    <ExpansionPanelDetails>
                        <Typography>Some more text</Typography>
                    </ExpansionPanelDetails>
                </ExpansionPanel>
            );
            arr.push(pointPanel);
            setPoints([...arr]);
        }

        return (
            <div className="flow">
                {points.map((point) => point)}
                <button className="add-waypoint" onClick={() => addPoint()}>Add</button>
            </div>
        ); }

代码沙箱链接:link

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    问题是当您渲染点时,您没有为它们提供任何道具(如扩展)。
    因此,当您单击扩展面板时,您会更改状态并触发 TransportFlow 上的渲染。
    point 是 TransportFlow 的子对象,但它不会渲染,因为 'point' 道具没有改变(因为你没有向它发送扩展道具,所以它不关心扩展状态何时改变)。
    解决方案是稍微改变结构,这样你就可以用道具提供“点”:

    const TransportFlow = () => {
      const [expanded, setExpanded] = React.useState("");
      const [points, setPoints] = React.useState([]);
      const handleChange = panel => (evt, isExpanded) => {
        setExpanded(isExpanded ? panel : false);
      };
      const addPoint = () => {
        const arr = [];
    
        arr.push('dummy'); //just to notify there's something in the array
        setPoints([...arr]);
      };
    
     const PointPanel = (props) => (
        <ExpansionPanel
          key="p1"
          expanded={props.expanded === "panel1"}
          onChange={props.handleChange("panel1")}
        >
          <ExpansionPanelSummary
            expandIcon={<ExpandMoreIcon />}
            id="panel1bh-header"
            aria-controls="panel1bh-content"
          >
            Hello
          </ExpansionPanelSummary>
          <ExpansionPanelDetails>
            <Typography>Some more text</Typography>
          </ExpansionPanelDetails>
        </ExpansionPanel>
      );
    
      return (
        <div className="flow">
          {points.map(point => <PointPanel  expanded={expanded} handleChange={handleChange}/>)}
          <button className="add-waypoint" onClick={() => addPoint()}>
            Add
          </button>
        </div>
      );
    };
    

    如您所见,我使用 addPoint 只是为了通知数组中有某些内容(如果您需要多个扩展面板 - 您需要稍微更改结构) 我还将 PointPanel 提取到一个组件中 - 这样您就可以为其提供道具。

    你可以参考这个CodeSandbox的例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 2018-05-21
      • 2012-05-04
      • 2020-12-28
      • 2019-10-26
      • 2020-08-09
      • 1970-01-01
      相关资源
      最近更新 更多