在React中隐藏和显示循环组件

时间:2018-01-29 04:25:02

标签: javascript reactjs react-router react-redux css-transitions

对于我正在构建的注册流程,我有一系列问题。目前,我正在遍历每个组件并将它们全部显示在一个页面上。我的问题是,我如何一次只显示一个?如何在每张幻灯片隐藏/显示时包含幻灯片左转换/动画?我希望每个问题都能单独显示,然后一旦用户点击下一个,它会隐藏第一个问题并显示第二个问题。我对React有点新,所以如果这是一个基本问题,我道歉但我无法弄明白。

以下是我的代码突破:

import React from 'react';
import Q1Name from './questions/Q1Name';
import Q2Birthday from './questions/Q2Birthday';
import Q3City from './questions/Q3City';
import Q4YouReady from './questions/Q4YouReady';
import Q5Setting from './questions/Q5Setting';
import Q6Length from './questions/Q6Length';
import Q7Email from './questions/Q7Email';


class SignUpPage extends React.Component {
    render() {
        const components = [Q1Name, Q2Birthday, Q3City, Q5Setting, Q6Length, Q7Email];
        const componentsToRender = components.map((Component, i) => (
            <Component key={i} />
        ));

        return (
            <div className = "container-fluid">
                <div className = "question-box">
                    {componentsToRender}
                </div>
            </div>
        );
    }
}

export default SignUpPage;

这是一个示例组件 - 它们都略有不同,所以我展示了两种主要类型:

第一个只有一个“下一个按钮”

import React from 'react';

class Q2Birthday extends React.Component {
    render() {
        return (
            <div className="questions">
                <h1 id="question-h1">When is your birthday?</h1>
                <form>
                    <div className="form-group">
                        <input type="date" className="form-control custom-form" id="birthdayInput" aria-describedby="birthday" placeholder="" />
                    </div>
                    <button type="submit" className="btn btn-custom btn-lg">Next Question!</button>
                </form>
            </div>
        );
    }
}

export default Q2Birthday;

第二个有3个按钮选项,用户可以从中选择

import React from 'react';

class Q6Length extends React.Component {
    render() {
        return (
            <div className="questions">
                <h1 id="question-h1">How long would you like your trip to be?</h1>
                    <button type="submit" className="btn btn-custom-select btn-lg">Just a weekend!</button>
                    <button type="submit" className="btn btn-custom-select btn-lg">A full week!</button>
                    <button type="submit" className="btn btn-custom-select btn-lg">I'm flexible!</button>
            </div>
        );
    }
}

export default Q6Length;

我还想在问题框类中为“questions”div添加幻灯片左转换。我一直在阅读react-transition-group,但我对如何实现它感到有些困惑。此外,使用此应用程序,我不需要存储表单数据的值。

1 个答案:

答案 0 :(得分:2)

  

我如何一次只显示一个?

鉴于您希望在它们之间进行幻灯片转换,您至少需要留下一个,并且下一个要在切换时显示在DOM中。当不切换时,可能只有DOM中的当前一个。但最简单的可能是将所有这些都放在DOM中,只是在视口的左/右侧有前一个/下一个。

所以要回答如何一次只显示一个问题,一种方法是将所有“旧”的容器翻译为100%的容器宽度,保留当前的那个,并翻译所有“下一个”那些是100%。

样式可能如下所示:

const oldStyle = {
  position: 'absolute',
  left: 0,
  top: 0,
  width: '100%',
  height: '100%',
  transform: 'translate(-100%)',
};
const currentStyle = {
  position: 'relative',
  transform: 'translate(0)',
};
const nextStyle = {
  position: 'absolute',
  left: 0,
  top: 0,
  width: '100%',
  height: '100%',
  transform: 'translate(100%)',
};

根据页面上的位置,您可能需要一些其他样式来隐藏溢出的下一张/上一张幻灯片。查找overflow属性。您可能还需要修复容器的高度或宽度 - 如果您发现非当前幻灯片具有意外(例如零)高度或宽度,请查看此内容。

要将适当的样式应用于每个面板,您需要知道哪个是哪个。

我建议跟踪父组件状态中的当前幻灯片索引。假设你在this.state.currentSlide中有这个。有了它,您可以选择这样的幻灯片样式:

const componentsToRender = components.map((Component, i) => (
  <Component key={i} style={i < this.state.currentSlide ? oldStyle : i === this.state.currentSlide ? currentStyle : nextStyle} />
));

为了让style道具传递到幻灯片,您需要稍微调整幻灯片。最简单的方法就是明确地传递那个:

<div className="questions" style={this.props.style}>

但是我们如何将当前幻灯片设置为状态,并使其保持最新状态?嗯,在最简单的情况下,您需要将其初始化为零。您的幻灯片组件需要在完成后告诉父级。你需要注意到这一点,并更新状态。

class SignUpPage extends React.Component {
  constructor(props) {
    super(props);

    // Set initial state
    this.state = {
      currentSlide: 0,
    };
  }

  // Handle notification from a child slide that we should move to the next
  nextSlide() {
    this.setState({
      currentSlide: this.state.currentSlide + 1,
    });
  }

  render() {
    ...
    const componentsToRender = components.map((Component, i) => (
      <Component key={i} style={this.props.style} onNext={this.nextSlide.bind(this)} />
    ));

子组件然后需要调用已经完成时传入的方法:

class Q2Birthday extends React.Component {
  handleSubmit(event) {
    // Don't perform an actual form submission
    event.preventDefault();

    // Notify the parent
    this.props.onNext();
  }

  render() {
    return (
      <div className="questions" style={this.props.style}>
        <h1 id="question-h1">When is your birthday?</h1>
        <form onSubmit={this.handleSubmit}>
          ...
  

如何在每张幻灯片隐藏/显示时包含幻灯片左转换/动画?

使用上述样式,可能就像为每张幻灯片设置以下样式一样简单:

transition: transform 0.5s;