【问题标题】:My animation is not working when re rendering my react component?重新渲染我的反应组件时我的动画不起作用?
【发布时间】:2019-12-28 03:05:05
【问题描述】:

所以,我的问题是我有一个组件,我给它关联了一个动画,并且在第一次渲染组件时它正在工作,但是在点击事件时,我更改了一些条件和一些与这个组件相关联的道具, 但是我的元素没有重新渲染,它只是改变了已经改变的东西,这意味着该元素没有从 dom 中删除并再次添加到 DOM 中,这就是我无法再次看到动画的原因,所以它没有重新渲染,或者我只是没有得到重新渲染的含义。

我当然尝试了一些解决方案,但我被卡住了,我尝试使用这种方法:

this.forceUpdate();

但同样,我仍然没有得到任何东西。

我认为我不必编写我编写的整个代码,因为它很多并且包含许多其他内容,但这是我认为需要的。

methodWillReceiveProps 在我的组件中:

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

props.isRendered 每次都返回 true,我检查了一些 console.log 方法。

这是渲染的:

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>);
 }

这里是 sass 文件和简单的渐变动画:

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

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

我将非常感谢您提供的任何帮助。

【问题讨论】:

  • 在 React 重新渲染组件之后,它将新渲染与旧渲染进行比较。并仅更新已更改的部分。因此,您可以尝试将 key prop 添加到您的 div 中。需要运行动画时更新此键值。
  • 您想在 onClick 事件时重新制作动画吗?
  • @user9408899 是的,我想重新制作动画。
  • @PavloKovchuk 所以 React 重新渲染方法不会从 dom 中删除元素并再次添加它们?
  • @TaouBen reactjs.org/docs/rendering-elements.html“React 只更新必要的东西”部分

标签: javascript reactjs sass


【解决方案1】:

您可以使用 keys 来确定反应是否发生了变化。这意味着您的渲染方法应如下所示:

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>);
 }

由于您需要在每次渲染时运行动画,因此每次都需要生成一些随机键(这就是我们在每次渲染时调用this.getRandomKey() 的原因)。您可以使用任何您喜欢的方式来实现 getRandomKey,尽管 shortid 非常适合生成唯一键。

【讨论】:

  • 我已经实现了一个解决方案并且它正在工作,但是你的想法看起来很棒,没有太多的代码!谢谢,我会考虑让我的代码质量更好。
【解决方案2】:

为组件设置动画的一种方法是将CSS class 附加到它。但是,动画完成后,您必须分离CSS class,以便在您想再次制作动画时重新附加。

这是一个基本的例子:

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>

请注意,我在ComponentDidUpdate 中将animateFlag 设置为false,这样当我再次单击Re-animate button 时,我可以将animate 类重新附加到div 元素。

我将超时持续时间设置为 3000 毫秒,因为动画需要 3000 毫秒。

【讨论】:

  • 这是我已经做过的,我只是想要一个代码更少的解决方案,谢谢!
猜你喜欢
  • 2019-06-26
  • 2020-03-08
  • 2021-10-27
  • 2014-12-06
  • 1970-01-01
  • 2018-12-27
  • 2018-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多