【问题标题】:styled-components animation back and forth based on propsstyled-components 基于 props 来回动画
【发布时间】:2018-10-29 15:26:58
【问题描述】:

我想让我的主要内容在特定道具上滑动并返回

所以我创建了动画,我想我会在道具发生变化的情况下添加反向。

现在下面的代码可以工作了,但唯一的问题是在第一页加载时我可以看到“slideOutContent”动画

我不希望它发生,这些幻灯片仅在侧边栏打开时才会发生,然后它会滑动内容。

const slideInContent = keyframes`
  from {
    margin-left: 0;
  }
  to {
    margin-left: 256px;
  }
`;
const slideOutContent = keyframes`
  from {
    margin-left: 256px;
  }
  to {
    margin-left: 0;
  }
`;

// Here we create a component that will rotate everything we pass in over two seconds
const MainContentBox = styled.div`
  animation: ${props => props.slide ? `${slideInContent} forwards` : `${slideOutContent}`};
  animation-duration: 0.5s;
  animation-timing-function: linear;
`;

这就是我使用这个组件的方式:

class PageWithDrawer ... {

    constructor(props) {
        super(props);
        this.state = {
            open: false
        };
    }

    toggleMenu() {
        this.setState(state => {
            return { open: !state.open };
        });
    }

    render() {
        ....other stuff

        <MainContentBox slide={this.state.open}>
              {this.props.children}
        </MainContentBox>

        ....other stuff
    }

【问题讨论】:

  • 我可以这样做,但它似乎是一个 hack。我想也许我可以找到更好的解决方案
  • 如果将上面的变量存储在state中,那么可以在getDerivedStateFromProps中检查之前的值是否为空。我不确定您将这些变量保存在哪里 - 您是在 render() 还是其他地方计算它们?无论在哪里,如果可以将它们移动到getDerivedStateFromProps,那么您可以检查它是否是第一次渲染,而不需要“hack”。
  • 谢谢@Al.G。添加了一些代码。如果您有任何其他想法会很高兴
  • @Al.G.刚刚测试了那个场景,如果我传递的道具没有改变,它似乎不会重新渲染“MainContentBox”。我不确定“样式组件”是如何隐藏的,但如果没有更改道具,可能确保不要重新渲染

标签: javascript reactjs css-animations styled-components


【解决方案1】:

目前您正在为MainContentBox 提供一个布尔值,但您有三个条件:SLIDE_IN、SLIDE_OUT 和 NO_SLIDE 条件。

为避免在首次渲染时使用额外的布尔标志,您可以将 state.open 设置为其他语言中所谓的 Enum - 这三个值中的任何一个的持有者。

// You can put these in a named {} for encapsulation
const NO_SLIDE = 0, SLIDE_OUT = 1, SLIDE_IN = 2;

class PageWithDrawer ... {
    constructor(props) {
        super(props);
        this.state = {
            open: NO_SLIDE, // Initial state
        };
    }

    toggleMenu() {
        this.setState(state => ({ open: state.open % 2 + 1 }));
    }

state % 2 + 1 是转换 0 → 1、1 → 2 和 2 → 1 的公式。

现在让我们将状态变量映射到动画属性字符串:

const stateToAnimation = {
    NO_SLIDE: 'none',
    SLIDE_OUT: slideInContent + ' forwards',
    SLIDE_IN: slideOutContent,
}

const MainContentBox = styled.div`
  animation: ${props => ${stateToAnimation[props.slide]}};
`; // other props...

您可能还需要用${} 包围props.slide,我不确定这种语法。

【讨论】:

  • 不错!比另一个标志好得多
【解决方案2】:

也许只使用transition 而不是animation。在这个特定的示例中,它应该可以完成这项工作,但我不确定它是否总是可行的。

【讨论】:

    猜你喜欢
    • 2021-09-19
    • 2021-09-22
    • 2020-06-07
    • 2020-05-28
    • 2020-01-16
    • 2019-02-18
    • 2021-05-12
    • 2018-04-27
    • 2018-04-15
    相关资源
    最近更新 更多