如何在React中从头开始动画而不重新渲染整个树

时间:2020-04-09 17:55:13

标签: css reactjs animation

我有3个盒子,上面有一些动画CSS。我想测试一下动画效果,然后将动画设置到可见区域,所以我将按钮连接到了盒子外面。

import React, { useState } from "react";
import "./appearance.css";
import "./animation.css"

export default function App() {
  const clickBox = i => setters[i](!states[i]);

  const [clicked0, setClicked0] = useState(false);
  const [clicked1, setClicked1] = useState(false);
  const [clicked2, setClicked2] = useState(false);

  const states = [clicked0, clicked1, clicked2];
  const setters = [setClicked0, setClicked1, setClicked2];

  function Box({ index }) {
    let className = "box";
    if (states[index]) className += " clicked";

    return (
      <div onClick={() => clickBox(index)} className={className}>
        {index}
      </div>
    );
  }

  const Boxes = [0, 1, 2].map(i => <Box index={i} key={i} />);
  const Buttons = [0, 1, 2].map(i => (
    <button onClick={() => clickBox(i)} key={i}>{i}</button>
  ));

  return (
    <div className="app">
      <div className="boxes-wrapper">{Boxes}</div>
      <div className="buttons-wrapper">{Buttons}</div>
    </div>
  );
}

如果我从box组件内部处理了box-click,则会正确动画一个box。

但是为了使按钮起作用,我必须将clicked状态置于父组件中。 这样做的不良影响是,当状态(父项)改变时,所有子项都将重新呈现。是的,这就是React的工作方式。

这意味着 1.您无法使用transition进行动画处理,因为每次重新渲染时这些框都是“第一次出现”,因此没有以前的状态 2.如果使用keyframes,动画可以工作,但是每次您单击一个框时,动画就会每次运行。

所以我想我知道问题出在哪里。但是我无法终生解决该问题!

1 个答案:

答案 0 :(得分:1)

在这里进行了一些修改,我就能实现我认为您正在寻找的东西-

https://codepen.io/soeltz/pen/abvbjwN

最显着的变化-

  • 我将您的Box组件移到了App之外。如果在App组件中定义了它,则每次App从状态更改中撤消时,都将重新定义它。移出它可使每个Box根据传递给它的道具处理自己的渲染。
  • 我不确定您的CSS文件中是否已包含此字符,但我在关键帧动画的末尾添加了forwards,以便按钮保持最终样式。