简体   繁体   English

重新渲染我的 React 组件时,我的动画不起作用?

[英]My animation is not working when re rendering my react component?

So, my problem is that I have a component, I associated an animation to it and it is working when the component is rendered for the first time, but on an event click I change some conditions and some props associated to this component, But my element is not re rendered, it is just changing what has been changed, that means that the element is not removed from the dom et added to the DOM again, that's why I am not able to see the animation again, so it is not re-rendered or I just did not get what re render means.所以,我的问题是我有一个组件,我将一个动画与它相关联,并且在第一次渲染组件时它正在工作,但是在事件单击时我更改了与该组件关联的一些条件和一些道具,但是我的元素没有被重新渲染,它只是改变了已更改的内容,这意味着该元素不会从 dom 中删除,而是再次添加到 DOM 中,这就是为什么我无法再次看到动画,所以它不是重新-rendered 或者我只是没有明白重新渲染的意思。

I tried some solutions of course, but I am stuck, I tried to use this method :我当然尝试了一些解决方案,但我被卡住了,我尝试使用这种方法:

this.forceUpdate(); this.forceUpdate();

But again, I am still not getting anything.但同样,我仍然没有得到任何东西。

I dont think I have to write the whole code I wrote, becuase it is a lot and includes many other things but This is what I think is needed.我不认为我必须编写我编写的整个代码,因为它很多并且包含许多其他内容,但这是我认为需要的。

methodWillReceiveProps in my component :我的组件中的 methodWillReceiveProps :

  componentWillReceiveProps(props) {
    if (props.isRerendered) {
      this.forceUpdate();
    }
  }

props.isRendered is returning true everytime, I checked with some console.log methods. props.isRendered 每次都返回 true,我检查了一些 console.log 方法。

This is what is rendered :这是呈现的内容:

render() {
    return (
      <div
        className={cs({
          "tls-forms": true,
          "tls-forms--large": this.props.type === "S",
          "tls-forms--medium tls-forms--login": !(this.props.type === "S")
        })}
      >
      // content here 
      </div>);
 }

And here is the sass file and the simple fading animation :这是 sass 文件和简单的淡入淡出动画:

.tls-forms {
  animation: formFading 3s;
  // childs properties here 
}

@keyframes formFading {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

I will really appreciate any help given.我将非常感谢您提供的任何帮助。

You could make use of keys that react is using to determine whether something has changed.您可以使用 react 使用的来确定某些内容是否已更改。 This means that your render method should look something like this:这意味着您的渲染方法应如下所示:

import shortid from "shortid";

getRandomKey = () => {
    return shortid.generate();
}

render() {
    return (
      <div
        key={this.getRandomKey()}
        className={cs({
          "tls-forms": true,
          "tls-forms--large": this.props.type === "S",
          "tls-forms--medium tls-forms--login": !(this.props.type === "S")
        })}
      >
      // content here 
      </div>);
 }

Since you need to run animation on each render, you'll need to generate some random key every time (that's why we are calling this.getRandomKey() on each render).由于您需要在每次渲染时运行动画,因此每次都需要生成一些随机键(这就是我们在每次渲染时调用this.getRandomKey()的原因)。 You can use whatever you like for your getRandomKey implementation, though shortid is pretty good for generating unique keys.您可以为 getRandomKey 实现使用任何您喜欢的东西,尽管 shortid 非常适合生成唯一键。

One way of animating a component is to attach a CSS class to it.动画组件的一种方法是将CSS class附加到它。 But, when animation is done, you have to detach the CSS class so that you can re-attach when you want to animate again.但是,当动画完成时,您必须分离CSS class以便您可以在想要再次制作动画时重新附加。

Here is a basic example:这是一个基本示例:

 class App extends React.Component { constructor(props) { super(props); this.state = { animateFlag: false }; } componentDidUpdate() { if (this.state.animateFlag) { setTimeout(() => { this.setState({ animateFlag: false }); }, 3000); } } render() { return ( <div className="App"> <button onClick={() => this.setState({ animateFlag: !this.state.animateFlag }) } > {this.state.animateFlag ? "Wait" : "Re-animate"} </button> <div className={this.state.animateFlag ? "text animate" : "text"}> Hello CodeSandbox </div> </div> ); } } const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);
 .text { font-size: 40px; } .text.animate { animation: formFading 3s; } @keyframes formFading { 0% { opacity: 0; } 100% { opacity: 1; } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

Note that, I am setting animateFlag to false in ComponentDidUpdate , so that when I click the Re-animate button again, I can re-attach the animate class to the div element.请注意,我在ComponentDidUpdate中将animateFlag设置为false ,这样当我再次单击Re-animate button时,我可以将animate类重新附加到div元素。

I set timeout duration to 3000ms because, the animation takes 3000ms.我将超时持续时间设置为 3000 毫秒,因为动画需要 3000 毫秒。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM