CSS transition未显示在React组件中

lf5gs5x2  于 11个月前  发布在  React
关注(0)|答案(1)|浏览(134)

组件应满足以下要求:
1.应显示列表中的元素,一次显示一个元素。
1.应该有两个按钮:Prev和Next,用于显示列表的上一个/下一个元素。
1.当点击Back/Next按钮时,应该会有某种滑动效果来指示上一个/下一个项目即将到来。
1.滑动效果的方向取决于点击的按钮。Next:从右到左,Prev:从左到右。
1.当第一次呈现第一个项目时,不应该有滑动效果。
我被困在第三步,CSS没有像预期的那样工作。
沙盒在这里:https://codesandbox.io/s/gracious-kapitsa-cxtsn6
以下是预期滑动过渡的CSS属性:

const styleSlideRtoL = {
  position: "relative",
  left: "150px",
  transition: "transform 0.3s ease-in-out",
  transform: "translateX(-150px)",
  color: "blue",
};

字符串
它们在列表元素中的使用方式如下:

const div1 = <div style={styleSlideRtoL}>Lorem Ipsum 1</div>;
const div2 = <div style={styleSlideRtoL}>Lorem Ipsum 2</div>;
const div3 = <div style={styleSlideRtoL}>Lorem Ipsum 3</div>;
const div4 = <div style={styleSlideRtoL}>Lorem Ipsum 4</div>;
const div5 = <div style={styleSlideRtoL}>Lorem Ipsum 5</div>;
const divs = [div1, div2, div3, div4, div5];


使用上述代码,未观察到跃迁效应。
但是,如果我对第1、3和5个div使用不同的样式(无滑动效果),则第2和4个div将获得预期的滑动效果。

const styleNoSlide = {
  // position: "relative",
  // left: "150px",
  // transition: "transform 0.3s ease-in-out",
  // transform: "translateX(-150px)",
  color: "orange",
}
const div1 = <div style={styleNoSlide}>Lorem Ipsum 1</div>;
const div2 = <div style={styleSlideRtoL}>Lorem Ipsum 2</div>;
const div3 = <div style={styleNoSlide}>Lorem Ipsum 3</div>;
const div4 = <div style={styleSlideRtoL}>Lorem Ipsum 4</div>;
const div5 = <div style={styleNoSlide}>Lorem Ipsum 5</div>;


问题:
1.为什么当我对所有的div都使用styleSlideRtoL时没有滑动效果?
1.如何正确地实现滑动效果,同时对现有代码进行最小的更改?
1.当使用替代样式时,第一、第三和第五格会比第二和第四格高出1 px。为什么?

u4vypkhs

u4vypkhs1#

首先,简单地挂载一个具有transition CSS属性的DOM元素不会导致“输入”动画的发生。对于transition,要使某个元素具有动画效果,必须首先加载一组CSS属性,然后更改为一组新的CSS属性。插入一个具有CSS属性的<div>不会导致任何动画的发生。
那么,为什么后一个例子只起了一半的作用呢?当您通过更新selectedIndex状态在这些div之间进行切换时,React使用的是它的协调过程,该过程会尽量减少从上一个DOM状态切换到下一个DOM状态所需的DOM操作量。React实际上只是通过将<div>的属性更改为新传递的样式来修补 * 现有的 * <div>
突然间,这满足了transition的要求,即DOM节点的CSS属性必须 * 更改 *,而不仅仅是插入最终状态。
您可以通过为每个<div>元素指定一个唯一的键来强制React的算法不重用相同的基本<div>元素来演示这一点:

const div1 = <div key={1} style={styleNoSlide}>Lorem Ipsum 1</div>;
  const div2 = <div key={2} style={styleSlideRtoL}>Lorem Ipsum 2</div>;
  const div3 = <div key={3} style={styleNoSlide}>Lorem Ipsum 3</div>;
  const div4 = <div key={4} style={styleSlideRtoL}>Lorem Ipsum 4</div>;
  const div5 = <div key={5} style={styleNoSlide}>Lorem Ipsum 5</div>;

字符串
现在您会注意到React将它们视为独特的元素,动画又完全消失了。
最简单的方法就是不需要在div之间切换,而是一直渲染 * 所有 * 的div,但实际上只有一个div是可见的(其余的会溢出视图)。然后调整transform的位置以响应点击按钮。

import "./styles.css";
import { useState } from "react";

export default function App() {
  const [selectedIndex, setSelectedIndex] = useState(0);

  const styleSlideWrapper = {
    width: "150px",
    overflow: "hidden",
    border: "3px solid magenta",
    borderRadius: "6px",
    whiteSpace: "nowrap"
  };

  const styleSlideRtoL = {
    position: "relative",
    color: "blue",
    display: "inline-block",
    width: "100%",
    transition: "transform 0.3s ease-in-out",
    transform: `translateX(-${100 * selectedIndex}%)`
  };

  const div1 = <div style={styleSlideRtoL}>Lorem Ipsum 1</div>;
  const div2 = <div style={styleSlideRtoL}>Lorem Ipsum 2</div>;
  const div3 = <div style={styleSlideRtoL}>Lorem Ipsum 3</div>;
  const div4 = <div style={styleSlideRtoL}>Lorem Ipsum 4</div>;
  const div5 = <div style={styleSlideRtoL}>Lorem Ipsum 5</div>;

  const divs = [div1, div2, div3, div4, div5];

  const handleBack = () => {
    if (selectedIndex > 0) {
      setSelectedIndex(selectedIndex - 1);
    }
  };
  const handleNext = () => {
    if (selectedIndex < divs.length - 1) {
      setSelectedIndex(selectedIndex + 1);
    }
  };
  return (
    <>
      <h1>Click a button to change item.</h1>
      <div style={styleSlideWrapper}>{divs}</div>
      <button onClick={() => handleBack()} disabled={selectedIndex === 0}>
        Prev
      </button>
      &nbsp;
      <button
        onClick={() => handleNext()}
        disabled={selectedIndex === divs.length - 1}
      >
        Next
      </button>
    </>
  );
}


工作中sandbox
注意这里不需要key,因为我们渲染的是所有div,而不是在它们之间切换,所以React修补单个div的问题永远不会发生。
这样做的主要原因是,您希望显示前一个正在退出。此外,元素在页面加载时被挂载,然后转换在满足transition工作原理的早期概述的 after 后进行调整。
值得注意的是,许多伟大的动画库使生活更容易,如framer-motion

相关问题