Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Card] Expandable Card mounts/un-mounts children #4750

Closed
killroy42 opened this issue Jul 20, 2016 · 4 comments
Closed

[Card] Expandable Card mounts/un-mounts children #4750

killroy42 opened this issue Jul 20, 2016 · 4 comments
Labels
component: card This is the name of the generic UI component, not the React module! performance

Comments

@killroy42
Copy link

Problem description

I'm using expandable cards to display asynchronous data. Load api on expand and populate list. Unfortunately a short list of just 30 items takes around 400ms+ to mount/render. This is ok, next to the time taken for the API cal (although I wish the rendering wouldn't freeze the progress spinner).

Unfortunately, closing and re-expanding the Card unmounts and re-mounts the child component, causing that 400ms freeze. Why is it not simply hidden with display: none or similar?

Steps to reproduce

Populate a Table with around 30 items inside an expandable card. Expand and collapse card and observe timings.

Versions

  • Material-UI: 0.16.0-alpha
  • React: 15.2.1
  • Browser: Chrome 51.0.2704.106 m
@mpontikes mpontikes mentioned this issue Aug 5, 2016
13 tasks
@oliviertassinari oliviertassinari added the component: card This is the name of the generic UI component, not the React module! label Dec 18, 2016
@oliviertassinari oliviertassinari changed the title Expandable Card mounts/un-mounts children [Card] Expandable Card mounts/un-mounts children Dec 18, 2016
@oliviertassinari
Copy link
Member

oliviertassinari commented Feb 12, 2017

Why is it not simply hidden with display: none or similar?

It's done this way to avoid paying 400ms+ upfront during the first render. I think that it's linked to #3289. I'm closing this issue as:

  • The performance of the <List /> has been improved on the next branch.
  • The <Card /> component is now composable. The previous expand logic is no implemented by the <Collapse /> component. You are free to use display: block/display: none if you find that solution better
  • The fiber reconciliation engine is going to remove that freeze.

@VillainJoKeR
Copy link

The <Card /> component is now composable. The previous expand logic is no implemented by the <Collapse /> component. You are free to use display: block/display: none if you find that solution better

@oliviertassinari I didn't quite get this. How can I use display:block/display:none in a Card component? I am sorry but I did not understand. Please help! And I don't think I see a component named <Collapse />. I think I have misinterpreted your comment!

@mbrookes
Copy link
Member

@VillainJoKeR

This example is using the Collapse transition. unMountOnExit is an optional prop.You can also use your own component there instead to show & hide the content.

@natrim
Copy link

natrim commented Aug 9, 2017

i know its a bit old, but i was searching the solution and the links are no longer working
so there is what i put together, in case someone else is searching the solution

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Card, CardText, CardTitle } from 'material-ui';
import { CardExpandable } from 'material-ui/Card/index';

export class Boxed extends Component {
  static propTypes = {
    children: PropTypes.node.isRequired,
    title: PropTypes.string,
    containerStyle: PropTypes.object,
    expandable: PropTypes.bool,
    initiallyExpanded: PropTypes.bool,
    showExpandableButton: PropTypes.bool,
  };

  static defaultProps = {
    containerStyle: {},
    expandable: false,
    initiallyExpanded: false,
    showExpandableButton: true,
  };

  state = {
    expanded: null,
  };

  componentWillMount() {
    this.setState({
      expanded: this.props.initiallyExpanded === true,
    });
  }

  handleExpandClick = () => this.setState({ expanded: !this.state.expanded });

  render() {
    const { children, title, containerStyle, expandable, initiallyExpanded, showExpandableButton, ...props } = this.props;

    let content;
    if (Array.isArray(children)) {
      content = React.Children.map(
        children,
        (child) => React.cloneElement(child, props)
      );
    } else {
      content = React.cloneElement(children, props);
    }

    let expander;
    let contentStyle = {};
    if (expandable && !this.state.expanded) {
      contentStyle = { height: 0, overflow: 'hidden', padding: 0, margin: 0 };
    }
    if (title && expandable && showExpandableButton) {
      expander = <CardTitle onClick={this.handleExpandClick} style={{ cursor: 'pointer' }}>
        {title}
        <CardExpandable
          expanded={this.state.expanded}
          onExpanding={this.handleExpandClick}
        />
      </CardTitle>;
    } else if (title) {
      expander = <CardTitle>{title}</CardTitle>;
    } else {
      expander = '';
    }

    return (
      <Card containerStyle={containerStyle}>
        {expander}
        <CardText style={contentStyle}>
          {content}
        </CardText>
      </Card>
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: card This is the name of the generic UI component, not the React module! performance
Projects
None yet
Development

No branches or pull requests

5 participants