【问题标题】:Google Material's ExpansionPanel for ReactJS not expanding by defaultReactJS 的 Google Material 扩展面板默认不扩展
【发布时间】:2019-03-26 18:44:57
【问题描述】:

我正在使用 Google 的 Material-UI 构建一个 ReactJS 应用程序。

在提交搜索后,我有以下子类显示在网格中。根据搜索是一种类型还是另一种类型,这个子类中的 ExpansionPanel 应该展开还是不展开。

这是在父组件中映射的类:

expandByDefault 布尔值是从父类传递的。

class SearchResults extends React.Component {
    render () {
        const { classes } = this.props;
        const { batchAndContents } = this.props;
        const { expandByDefault } = this.props;
        return (
            <div>
                <ExpansionPanel defaultExpanded={expandByDefault} >
                    <ExpansionPanelSummary>
                    <Typography className={classes.heading}>Box {batchAndContents.sequenceCode}</Typography>
                    </ExpansionPanelSummary>
                    <ExpansionPanelDetails>
                        <SearchResultsTable contents={batchAndContents.contents}/>
                    </ExpansionPanelDetails>
                </ExpansionPanel>
            </div>
        )
    }
}

这里是父类的渲染方法: 你可以在我的自定义类 SearchResults 中看到,我传递了一个名为 expandByDefault 的道具。

render () {
        return (
            <div>
              . . . . .
              . . . . .
              . . . . .
              <Grid container spacing={24} style={{padding: 24}}>
                {this.state.searchResults.map((searchResult) => (
                    <Grid item key={searchResult.sequenceCode+searchResult.state}  xs={12}>
                        <SearchResults batchAndContents={searchResult} expandByDefault={this.state.lastSearchType === "ContentBarcode"}/>
                    </Grid>
                ))}
            </Grid>
            </div>
        )
    }

我已经尝试了几种变体来使其正常工作,但我似乎无法理解我缺少什么。

有趣的是,当我最初执行搜索时,ExpansionPanel 的属性 defaultExpanded 设置为 true,它可以工作。但是,如果我不刷新页面并使用不同类型执行另一次搜索,那么当类型应该导致该行为时,结果不会倒塌。

如果我最初执行搜索并且将 ExpansionPanel defaultExpanded 设置为 false,则会发生相同的行为。它在点击时展开,并且默认折叠,但是,当将搜索类型更改为应该导致默认展开面板的内容时,它不起作用。

感谢任何指导。

【问题讨论】:

  • 你想要expanded,而不是defaultExpanded
  • @Herohtar 感谢您的回复,这实际上不是问题,我在下面发布了我的解决方案。谢谢!

标签: javascript reactjs material-ui


【解决方案1】:

我遇到了同样的问题。该属性似乎只看初始渲染中的值。

如果它在初始渲染中未定义或具有默认值,那么即使this.props.expandByDefault 的值发生更改,也会使用它;它只是被忽略了。

如果你想使用这个特性,你必须避免在 prop 收到“正确”值之前完全渲染组件。

一开始看起来很奇怪,但仔细想想就明白了。一旦最初呈现,API 不想冒险覆盖用户采取的操作,并且不希望意外地关闭或打开对话框。它可能会锁定面板。

【讨论】:

    【解决方案2】:

    defaultExpanded 属性只定义了组件的默认 状态——即,在第一次渲染时是否展开面板。以后更改此值不会影响面板当前是否展开。

    要使面板根据应用中的变化展开或折叠,您需要使用expanded 属性。来自docs

    如果是true,则展开面板,否则折叠它。设置这个属性可以控制面板。

    【讨论】:

    • 您好,谢谢您的回复!组件本身实际上可以切换打开和关闭,而无需手动管理它。我知道您可以设置一个 onClick 动作侦听器,然后将其打开或关闭。我确实发现了问题,我会在一秒钟内发布。再次感谢。
    • 我对为什么这个答案被否决感到有点困惑,我认为这是由于误解。后来我意识到这实际上与我的答案相同。 +1
    【解决方案3】:

    这里的问题是&lt;Grid item ... /&gt; 父视图中&lt;Grid item ... /&gt; 元素上的键没有改变。

    当使用不同类型执行搜索时,会显示相同的数据,只是显示方式不同。

    据我了解,如果 react 看到具有相同数据的相同键,则不需要重新渲染,即使有状态作为道具传递给孩子。在我的情况下,状态被作为道具传递给&lt;Grid item ... /&gt;中的孩子。

    作为解决方案,我将搜索类型附加到键中。所以现在当搜索类型发生变化时,保存结果的键也会发生变化,&lt;Grid item ... /&gt; 的子元素会被触发重新渲染。

    抱歉,我的解释不是最好的,我对 ReactJS 有一些实践经验,但从“幕后”的角度来看,我不能说得那么好。

    【讨论】:

    • 这基本上就是我的回答;你不能使用defaultExpanded,因为组件没有被重新渲染。然而,强制 React 重新渲染组件并不是一个理想的解决方案,因为它会降低性能并影响用户体验。 expanded 会是更好的选择并且更简单一些,除非您还需要允许用户展开/折叠这些面板,在这种情况下您需要添加一些额外的逻辑。
    猜你喜欢
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多