React过渡组(v1)在重新渲染时不激活过渡

时间:2018-01-12 15:58:05

标签: javascript css reactjs react-transition-group

我有一个简短的测验应用程序,我正在尝试应用一些动画。我的想法是,每次只显示一个问题,每个问题之间都有过渡。我使用create-react-app作为样板,我使用react-transitions-group v1来应用所述转换。现在我的根组件看起来像这样:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Panel from './components/Panel';
import Results from './components/Results';
import Intro from './components/Intro';
import Form from './components/Form';

class App extends Component {

  constructor (props) {
    super (props);
    this.state = {
      collaborator: 0,
      pilot: 0,
      producer: 0,
      harmonizer: 0,
      counter: 0,
      questions: [
       'Where do you put the most effort on a day-to-day basis?',
       'What are your biggest blind spots?',
       'In what settings do you thrive?',
       'In what settings do you struggle?'
      ],
      answers: [
        [
          {answer: 'Team building', archetype: 'collaborator'},
          {answer: 'Directing strategy', archetype: 'pilot'},
          {answer: 'Driving task completion', archetype: 'producer'},
          {answer: 'Keeping processes and relationships running smoothly', archetype: 'harmonizer'}
        ],
        [
          {answer: 'Setting a clear direction and creating a personal brand', archetype: 'collaborator'},
          {answer: 'Making space for others and planning for the longterm', archetype: 'pilot'},
          {answer: 'Connecting with team members and innovating', archetype: 'producer'},
          {answer: 'Accepting ambiguity and addressing conflict', archetype: 'harmonizer'}
        ],
        [
          {answer: 'Settings where team members are seeking coaching and development', archetype: 'collaborator'},
          {answer: 'Ambiguous and high growth environments', archetype: 'pilot'},
          {answer: 'Organizations with clear structures and processes', archetype: 'producer'},
          {answer: 'Volatile settings that need to be tamed', archetype: 'harmonizer'}
        ],
        [
          {answer: 'Settings where unilateral decision making is required', archetype: 'collaborator'},
          {answer: 'Conservative environments that discourage innovation', archetype: 'pilot'},
          {answer: 'Teams where each member desires independence', archetype: 'producer'},
          {answer: 'Anywhere tough feedback needs to be given', archetype: 'harmonizer'}
        ]
      ]
    }
    this.onSelect = this.onSelect.bind(this);
    this.onSelectIntro = this.onSelectIntro.bind(this);
  }

  onSelect(value) {
    this.setState(prevState => {
      return {
        [value]: prevState[value] + 1,
        counter: prevState.counter + 1
      }
    })
  }

  onSelectIntro() {
    this.setState(prevState => {
      return { counter: prevState.counter + 1 };
    })
  }

  render() {
    switch (this.state.counter) {
      case 0:
        return <Intro onClick={this.onSelectIntro}/>;
        break;
      case 1: case 2: case 3: case 4:
         return <Panel 
          question={this.state.questions[this.state.counter - 1]}
          answers={this.state.answers[this.state.counter - 1]}
          onSelect={this.onSelect}
        />;
        break;
      case 5:
        return <Results />;
        break;
    }
  }
}

export default App;

我的Panel组件看起来像这样:

import React from 'react';
import Form from './Form';
import PropTypes from 'prop-types';

function PanelOne (props) {
    return (
        <div>
            <Form question={props.question} answers={props.answers} onSelect={props.onSelect}/>
        </div>
    )
}

PanelOne.propTypes = {
  answers: PropTypes.array.isRequired,
  onSelect: PropTypes.func.isRequired
};

export default PanelOne;

Form是应用我的过渡的地方,它看起来像这样:

import React from 'react';
import PropTypes from 'prop-types';
import { RadioGroup, RadioButton } from 'react-radio-buttons';
import { CSSTransitionGroup } from 'react-transition-group';

function Form (props) {
    return (
        <div>
            <CSSTransitionGroup 
                transitionName='slide'
                transitionEnterTimeout={300}
                transitionLeaveTimeout={300}
            >
                <h3>{props.question}</h3>
                <RadioGroup onChange={props.onSelect}>
                    {
                        props.answers.map(answer => 
                            <RadioButton key={answer.answer} value={answer.archetype}>
                                {answer.answer}
                            </RadioButton>
                        )
                    }
                </RadioGroup>
            </CSSTransitionGroup>
        </div>
    )
}

Form.propTypes = {
  answers: PropTypes.array.isRequired,
  onSelect: PropTypes.func.isRequired
};

export default Form;

最后,这是我的index.css文件:

body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
}

.slide-enter {
  opacity: 0.01;
}
.slide-enter.slide-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}
.slide-leave {
  opacity: 1;
}
.slide-leave.slide-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}

我希望当我点击问题的答案时,将在应用转换后显示下一个问题。但是,当我点击答案时,实际发生的是下一个问题立即显示,两个问题之间没有过渡。因为我在这里做错了,我真的很茫然......

1 个答案:

答案 0 :(得分:0)

您的表单和面板组件是功能组件,因此它们没有实例。

React Components, Elements, and Instances

  

只有声明为类的组件才有实例,而你永远不会直接创建它们:React会为你做这件事。

因此,当他们的道具发生变化时,底层的DOM树可能会被删除。这样就不会留下动画。

Reconciliation

  

当组件更新时,实例保持不变,以便在渲染之间保持状态。

您应该尝试使用Class组件。