ReactJS - 简单的SlideShow通信切换到父级

时间:2016-02-01 22:58:36

标签: reactjs

关注的两个组成部分,SlideShow&对照

目标

  1. 切换时的chevron控制,更改“下一个”状态并将该“下一个”值传递给父级。

  2. 父级将currentSlide状态更改为传递的下一个值。

  3. 问题

    孩子的callbackParent prop返回一个值,但我似乎很难让父母读取它。

    幻灯片演示:

    var slideData= [{....}]
    
    export default class Slideshow extends Component {
    
      constructor(props) {
        super(props);
        this.state = {
          currentSlide: 0,
          data: []
        };
      }
    
      componentWillMount() {
        this.setState({ data: slideData });
      }
    
      handleClick(next) {
        this.setState({ currentSlide: next });
      }
    
      render() {
        const data = this.state.data;
        const currentSlide = this.state.currentSlide;
        return (
          <div className="slideshow">
            ...
            <Controls data={ data } currentSlide={ currentSlide } 
             callbackParent={ this.handleClick.bind(this, currentSlide) } />
          </div>
        );
      }
    }
    

    控件:

    class Controls extends Component {
    
      ....
    
      toggleNext() {
        const current = this.state.currentSlide;
        let next = current + 1;
        if (next > this.props.data.length - 1) {
          next = 0;
        }
        this.props.callbackParent(this.setState({ currentSlide: next }));
      }
    
      togglePrev() {
         .....
      }
    
      render() {
        return (
          <div className="controls">
             ......
            <div className="toggle toggle--next"
              onClick={ this.toggleNext.bind(this, this.state.currentSlide) }
            >Next
            </div>
          </div>
        );
      }
    }
    

    问题:

    如何成功将孩子返回的“下一个”值传递给父母。

    谢谢。

1 个答案:

答案 0 :(得分:0)

这不是解释我犯错的地方,而是整个解决方案:

enter image description here

import React, { Component, PropTypes } from 'react';
require('./styles.css');

const slideData = [
  {
    id: 'slide1',
    imagePath: '/images/cats/slide_1.jpg',
    imageAlt: 'Slide 1 Image',
    title: 'Slide 1',
    subtitle: 'Slide 1 Image SubTitle',
    text: 'Slide 1 Image Text',
    action: 'Slide 1 Image Action',
    actionHref: 'href'
  },
  {
    id: 'slide2',
    imagePath: '/images/cats/slide_2.jpg',
    imageAlt: 'Slide 2 Image',
    title: 'Slide 2',
    subtitle: 'Slide 2 Image SubTitle',
    text: 'Slide 2 Image Text',
    action: 'Slide 2 Image Action',
    actionHref: 'href'
  },
  {
    id: 'slide3',
    imagePath: '/images/cats/slide_3.jpg',
    imageAlt: 'Slide 3 Image',
    title: 'Slide 3',
    subtitle: 'Slide 3 Image SubTitle',
    text: 'Slide 3 Image Text',
    action: 'Slide 3 Image Action',
    actionHref: 'href'
  }
];
export default class Slideshow extends Component {

  constructor(props) {
    super(props);
    this.state = {
      currentSlide: 0,
      data: []
    };
  }

  componentWillMount() {
    this.setState({ data: slideData });
  }

  handleClick(nextSlide) {
    this.setState({ currentSlide: nextSlide });
  }

  render() {
    const data = this.state.data;
    const currentSlide = this.state.currentSlide;
    return (
      <div className="slideshow">
        <Slides data={ data } currentSlide={ currentSlide } />
        <Pagination data={ data } callbackParent={ this.handleClick.bind(this) } />
        <Controls data={ data } currentSlide={ currentSlide } callbackParent={ this.handleClick.bind(this) } />
      </div>
    );
  }
}
class Slides extends Component {

  constructor(props) {
    super(props);
  }

  static propTypes = {
    currentSlide: PropTypes.number.isRequired,
    data: PropTypes.array.isRequired
  }

  render() {
    const data = this.props.data;
    const currSlide = this.props.currentSlide;
    const slidesNodes = data.map(function (slideNode, index) {
      const isActive = currSlide === index;
      return (
        <Slide active={ isActive } key={ slideNode.id }
          imagePath={ slideNode.imagePath } imageAlt={ slideNode.imageAlt }
          title={ slideNode.title } subtitle={ slideNode.subtitle }
          text={ slideNode.text } action={ slideNode.action }
          actionHref={ slideNode.actionHref }
        />
      );
    });
    return (
      <div className="slides">
        { slidesNodes }
      </div>
    );
  }
}
class Slide extends Component {

  constructor(props) {
    super(props);
  }

  static propTypes = {
    action: PropTypes.any.isRequired,
    active: PropTypes.bool.isRequired,
    actionHref: PropTypes.any.isRequired,
    imagePath: PropTypes.string.isRequired,
    imageAlt: PropTypes.string.isRequired,
    subtitle: PropTypes.string.isRequired,
    text: PropTypes.string.isRequired,
    title: PropTypes.string.isRequired
  }

  render() {
    const classes = this.props.active ? 'slide slide--active' : 'slide';
    return (
      <div className={ classes }>
        <img src={ this.props.imagePath } alt={ this.props.imageAlt }/>
        <h2>{ this.props.title }</h2>
        <h3>{ this.props.subtitle }</h3>
        <p>{ this.props.text }</p>
        <a href={ this.props.actionHref }>{ this.props.action }</a>
      </div>
    );
  }
}
class Controls extends Component {

  constructor(props) {
    super(props);
  }

  static propTypes = {
    callbackParent: PropTypes.func.isRequired,
    currentSlide: PropTypes.number.isRequired,
    data: PropTypes.array.isRequired
  };

  toggleNext() {
    const current = this.props.currentSlide;
    const data = this.props.data;
    let next = current + 1;
    if (next > data.length - 1) {
      next = 0;
    }
    this.props.callbackParent(next);
  }

  togglePrev() {
    const current = this.props.currentSlide;
    const data = this.props.data;
    let prev = current - 1;
    if (prev < 0) {
      prev = data.length - 1;
    }
    this.props.callbackParent(prev);
  }

  render() {
    return (
      <div className="controls">
        <div className="toggle toggle--prev" onClick={ this.togglePrev.bind(this) } >Prev</div>
        <div className="toggle toggle--next" onClick={ this.toggleNext.bind(this) } >Next</div>
      </div>
    );
  }
}
class Pagination extends Component {

  constructor(props) {
    super(props);
  }

  static propTypes = {
    callbackParent: PropTypes.func.isRequired,
    data: PropTypes.array.isRequired
  }

  handleClick(slideNum) {
    this.props.callbackParent(slideNum)
  }


  render() {
    const handleClick = this.handleClick.bind(this);
    const paginationNodes = this.props.data.map(function (paginationNode, index) {
      return (
        <Pager id={ paginationNode.id } key={ index }
               title={ paginationNode.title } index={ index }
               pagerClick={ handleClick }
        />
      );
    });
    return (
      <div className="pagination">
        { paginationNodes }
      </div>
    );
  }
}
class Pager extends Component {

  constructor(props) {
    super(props);
  }

  static propTypes = {
    pagerClick: PropTypes.func.isRequired,
    id: PropTypes.any.isRequired,
    title: PropTypes.string.isRequiredv
  };

  toggleSlide() {
    this.props.pagerClick(this.props.index);
  }

  render() {
    return (
      <span className="pager" onClick={ this.toggleSlide.bind(this) }>{ this.props.title }</span>
    );
  }
}