无状态React组件

时间:2018-05-07 15:09:35

标签: reactjs animation popmotion

我已经开始使用react-pose,并且对React中的大多数动画设置都有一个问题。

  1. 在首次渲染时,您似乎无法在组件上触发动画?
  2. 这就是我问上述问题的原因。下面是尝试使用无状态组件的react-pose示例。我希望当我将它添加到我的main.js渲染时就像这样。它会

    1. 首先安装FadeDiv组件,并将initialPose设置为不透明度为0
    2. 然后设置pose ="输入"在渲染上设置为不透明度:1。但事实并非如此 案子。如果是这样的话,那将是美好而简单的。

      import React from 'react';
      import posed from 'react-pose';
      
      const FadeDiv = posed.div({
        enter: { opacity: 1 },
        before: { opacity: 0 },
        initialPose: 'before'
      });
      
      export const Wrapper = () => (
       <FadeDiv pose="enter">
         <div>This is a fading div</div>
       </FadeDiv>
      ); 
      
    3. 如果我错了,请纠正我,但这是我认为正在发生的事情。 当React安装无状态或任何组件时,它不知道initialPose,直到它完全安装在这个阶段为时已晚,它只是将组件的不透明度设置为pose =&#34;输入&#34;这就是为什么我没有看到0-1的动画,因为它的不透明度设置为&#34;输入&#34; 这是不透明度1.所以它只是没有任何显示动画。

      好的,如果以上是正确的,那么我在下面添加了这个设置,这是添加状态的额外模板,但我想React是必要的。

      import React, { Component } from 'react';
      import posed from 'react-pose';
      
      const FadeDiv = posed.div({
        enter: { opacity: 1 },
        before: { opacity: 0 },
        initialPose: 'before'
      });
      
      class Wrapper extends Component {
        constructor(props) {
          super(props);
          this.state = {
            isEnter: false
          };
        }
      
        componentDidMount() {
          this.setState({
            isEnter: true
          });
        }
      
        render() {
          return (
            <FadeDiv pose={this.state.isEnter ? 'enter' : 'before'}>
              <div>This is a fading div</div>
            </FadeDiv>
          );
        }
      }
      
      export default Wrapper;
      

      现在一切正常但是我必须强制第二次渲染才能在第一次渲染(挂载组件)时在isEnter之间切换,然后在组件挂载挂钩时设置为true。

      对于长篇大论的解释感到抱歉,但对我来说很重要。 这个额外数量的样板是唯一具有简单div动画的解决方案吗?首先使用componentDidMount的生命周期钩子包装组件,以使用state触发第二次渲染。 我认为她发生的事情对我来说是一个分解,而其他人可能理解的是:

      1. initial render pose = {this.state.isEnter? &#39;进入&#39; :&#39;在设置之前 到&#34;之前&#34;这意味着FadeDiv组件是不透明度0
      2. 然后第二次渲染由状态更改触发设置 姿势=&#34;输入&#34;将不透明度设置为1并为组件设置动画 从0 - 1。
      3. 这是一个正确的假设吗?

        考虑到这一点,每次你需要一个简单的动画时,人们真的会在React中使用额外的样板来解决动画问题。是的我知道你可以使用css,但你仍然需要等待组件挂载以将第一个样式设置为opacity = 0然后重新渲染以设置opacity = 1.但是这里的问题是关于Popmotion的反应 - 当我使用DOM元素的动画时,我想React本身及其陷阱。

2 个答案:

答案 0 :(得分:1)

https://github.com/Popmotion/popmotion/issues/361#issuecomment-395037669

您应该检查一下。

<Box
  style={styles}
  initialPose="closed"
  pose="open"
/>

闭合的初始姿势下,Box将在安装时进行动画处理。

这是Codesandbox示例:

https://codesandbox.io/s/n5y2v17rwl

答案 1 :(得分:-1)

我一直在使用react-spring,从文档来看,它与react-pose非常相似。

您缺少的重要一件事是transition属性,该属性与opacity属性配合得很好。

我没有像您那样创建功能组件,而是通过直接更改不透明度来处理动画。

class App extends Component {
  constructor() {
    super()
    this.state ={
      opacity: 0
    }
  }
 componentDidMount() {
   this.handleTransition()
 }

 handleTransition = () => (
   setTimeout(() => this.setState({opacity: 1}), 400 )
 )

 render() {
  return (
    <div className="App">
      <div style={{opacity: this.state.opacity, transition: "opacity 3s ease"}}>
      <h1>Faded Div </h1>
      </div>
    </div>
  );
 }
}

https://codesandbox.io/s/6v6l7xo4zz

目前,我发现设置状态的不透明度是处理过渡的唯一方法之一。并不是那么糟糕,只有2-3行额外的代码。