React / Redux轮播

时间:2018-09-27 21:00:18

标签: javascript reactjs redux

因此,我正在为自己的简历创建自己的网站,遇到了我不确定如何解决的问题。我正在使用React和Redux,出现的问题是,我想要使用集成了适当的redux的react使用轮播类型格式显示小的小项目。目前我的文件结构如下: src/ actions/ index.js components/ App.js NavBar.js Projects.js projects/ Project1/ Project2/ containers/ Main.js reducers/ index.js projects.js

我不确定要如何实现自己想要的目标,我一直在寻找一个好的解决方案,但还没有真正遇到任何问题。我还是比较陌生的。我不想显示一个项目,向下滚动显示下一个项目,再滚动更多...我尝试过的是:

let components = [{TicTacToe}, {}];
let index = 0;

export default class Projects extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      component: components[0]
    };
  }
  renderProject(i)
  {
    this.setState({component: components[i]});
  }

  backRotate()
  {
    index--;
    if(index < 0)
    {
      index = components.length - 1;
    }
    this.renderProject(index);
  }

  forwardRotate()
  {
    index++;
    if(index >= components.length)
    {
      index = 0;
    }
    this.renderProject(index);
  }

  render() {
    return(
    <div>
      <button onClick='backRotate'>Back</button>
      <div class='carousel-container'>
        <this.state.component />
      </div>
      <button onClick='forwardRotate'>Next</button>
    </div>
  ) }
}

我本来以为这可以用,但是确实坏了。我目前正在我的组件文件夹中通过App.js运行,添加了NavBar组件,然后添加了Main.js容器。之所以使用此容器,是因为我需要一个后退和前进按钮来旋转每个项目,就像图像轮播一样。我曾考虑过添加所有组件,然后只是隐藏和显示,但这似乎是不必要的资源浪费,应该有一种更好的方法来实现这一目标。

是否可以通过单击按钮来替换组件?完全删除原始组件并在其中添加新组件?如果是这样,我还如何使用redux完成此操作?目前,我的项目减速器只是一个占位符。

1 个答案:

答案 0 :(得分:0)

首先,它中断了,因为components数组包含对象,而React无法拥有对象。

有效的React元素可以是节点(HTMLElement,React Component,文本或数字)或节点数组。

如果您只想将React组件保留在一个集合中并能够选择要显示的组件,则首先必须删除components数组中的括号,如下所示:

let components = [TicTacToe, AnotherComponent];

您还需要修复backRotateforwardRotate处理程序。它们不能像html中那样是字符串(请注意大括号而不是引号):

<button onClick={this.backRotate}>Back</button>
<button onClick={this.forwardRotate}>Next</button>

...并且必须绑定到您的组件实例。绑定它们的一种方法是使用Function.prototype.bind方法。应该在构造函数中完成:

constructor(props) {
    super(props);
    this.backRotate = this.backRotate.bind(this);
    this.forwardRotate= this.forwardRotate.bind(this);
}

没有绑定this不会引用您的组件实例,并且在处理程序中调用它肯定会失败。

TicTacToeAnotherComponent必须是扩展React.ComponentReact.PureComponent的类,或者必须是道具的纯功能组件。

更清晰,可能会更支持声明包含组件的大写变量:

render() {
    const Comp = this.state.component;
    return (
        <div>
            <button onClick={this.backRotate}>Back</button>
            <div class='carousel-container'>
                <Comp />
             </div>
             <button onClick={this.forwardRotate}>Next</button>
        </div>
     );
}

最后,您应该使index成为组件的状态(随组件的控件而改变),并使components成为道具(其在组件内不会改变)。

您将设置当前组件索引,而不是将当前组件设置为状态:

import React from 'react':
import PropTypes from 'prop-types';
import { TicTacToe, AnotherComponent } from 'path/to/named/imports/TicTacToeAndAnotherComponent';

export default class Projects extends React.Component {
    static propTypes = {
        components: PropTypes.any,
    }
    static defaultProps = {
        components: [TicTacToe, AnotherComponent],
    }
    constructor(props) {
        super(props);
        this.state = {
            index: 0,
        };
        this.backRotate = this.backRotate.bind(this);
        this.forwardRotate= this.forwardRotate.bind(this);
    }
    backRotate() {
        const { components } = this.props;
        const { index } = this.state;
        if(index - 1 < 0) {
            this.setState(() => ({ index: components.length - 1 }));
        } else {
            this.setState(() => ({ index: index - 1 }));
        }
    }

    forwardRotate() {
        const { components } = this.props;
        const { index } = this.state;
        if(index >= components.length) {
            this.setState(() => ({ index: 0 }));
        } else {
            this.setState(() => ({ index: index + 1 }));
        }
    }
    render() {
        const Comp = this.props.components[this.state.index];
        return (
            <div>
                <button onClick={this.backRotate}>Back</button>
                <div class='carousel-container'>
                    <Comp />
                 </div>
                 <button onClick={this.forwardRotate}>Next</button>
             </div>
         );
    }
}

无论哪种方式,Redux都无法帮助您。

Redux的目的主要是提供单一数据源(单一事实源),提供操作和简化程序以对该数据进行突变,并通知注册的组件以监听存储更新。您是否将轮播与商店连接都与解决iisue无关。