最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Material UI transition out and in on single button click - Stack Overflow

programmeradmin3浏览0评论

In the Material UI Transitions doc, there are examples where a button triggers a transition. I have a case where a button triggers a state change and I want the former data to transition out and then the new data to transition in. The only way I have found to do this is with setTimeout. Is there a better way?

In CodeSandbox

import React from "react";
import Slide from "@material-ui/core/Slide";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";

const words = ["one", "two", "three"];
const transitionDuration = 500;

class TransitionCycle extends React.Component {
  state = {
    activeIndex: 0,
    elementIn: true
  };

  onClick = () => {
    this.setState({
      elementIn: false
    });
    setTimeout(() => {
      this.setState({
        elementIn: true,
        activeIndex: (this.state.activeIndex + 1) % words.length
      });
    }, transitionDuration);
  };

  render() {
    const { activeIndex, elementIn } = this.state;

    return (
      <div>
        <Button onClick={this.onClick}>Cycle</Button>
        <Slide
          in={this.state.elementIn}
          timeout={transitionDuration}
          direction="right"
        >
          <Typography variant="h1">{words[this.state.activeIndex]}</Typography>
        </Slide>
      </div>
    );
  }
}

export default TransitionCycle;

Is this the best way to do back to back transitions in Material UI? It feels odd to use setTimeout.

In the Material UI Transitions doc, there are examples where a button triggers a transition. I have a case where a button triggers a state change and I want the former data to transition out and then the new data to transition in. The only way I have found to do this is with setTimeout. Is there a better way?

In CodeSandbox

import React from "react";
import Slide from "@material-ui/core/Slide";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";

const words = ["one", "two", "three"];
const transitionDuration = 500;

class TransitionCycle extends React.Component {
  state = {
    activeIndex: 0,
    elementIn: true
  };

  onClick = () => {
    this.setState({
      elementIn: false
    });
    setTimeout(() => {
      this.setState({
        elementIn: true,
        activeIndex: (this.state.activeIndex + 1) % words.length
      });
    }, transitionDuration);
  };

  render() {
    const { activeIndex, elementIn } = this.state;

    return (
      <div>
        <Button onClick={this.onClick}>Cycle</Button>
        <Slide
          in={this.state.elementIn}
          timeout={transitionDuration}
          direction="right"
        >
          <Typography variant="h1">{words[this.state.activeIndex]}</Typography>
        </Slide>
      </div>
    );
  }
}

export default TransitionCycle;

Is this the best way to do back to back transitions in Material UI? It feels odd to use setTimeout.

Share Improve this question asked Dec 17, 2018 at 1:11 Scotty HScotty H 6,7147 gold badges45 silver badges100 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 1

It's possible to use CSS transitions directly and to use an event listener instead of setTimeout to detect when the transition has happened, Mozilla provides documentation on that here: https://developer.mozilla/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_pletion_of_a_transition

class MyComponent extends React.Component {
  updateTransition = () => {
    this.setState({
      elementIn: true,
      activeIndex: (this.state.activeIndex + 1) % words.length
    });
  }

  ponentDidMount() {
    elementRef.addEventListener("transitionend", updateTransition, true);
  }
}

Don't forget to add the event listener on mounting and remove it on unmounting the ponent.

I think conditionally render all 3 Slides could solve your problem, here.

I also checked the source codes of Transition and it also uses setTimeout in the end, so I think it's not that "weird" to use it, but if the ponent already wraps the low-level api (I mean setTimeout) for us then we surely don't want to use it.


Edit:

As OP's ment, I found that I misread his example and didn't notice the out transition, so I modified my codes to meet the requirement. Now the previous Slide exits pletely, then the next one enters. Everything is done by the ponent's designed props. (Still, the underlying Transition source codes are just wrapping the Rudolf Olah's method, but I just try to use only the designed props)

However, by only using Transition's props, I think it's impossible to achieve the "delay" entering what OP did using setTimeout, so if OP still wants to have that small delay before "Two" enters, you might still have to use setTimeout.

发布评论

评论列表(0)

  1. 暂无评论