点击按钮后对滑块中的更改幻灯片做出反应

时间:2019-04-29 14:38:11

标签: reactjs react-component

我有一个通过这种方式实现的补充工具栏:

import React from "react";
import './MySidebar.scss';
import {slide as Menu } from 'react-burger-menu'

export class MySidebar extends React.Component {


  constructor(props) {
    super(props);
  }


 changeSlide = (e) => {
   console.log("Clicked " + e.currentTarget.id); //get text content of
 }


  render() {


    return (
        <Menu customCrossIcon={false}>
            <button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project1">Project 1</button>
      <button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project2">Project 2</button>
        </Menu>
    );
  }
} 

然后,我有一个名为ProjectSliderComponent的组件,可实现轮播的行为。通过以下方式完成:

import React from "react";
import Slider from "react-slick";
import './project-carousel.component.css';
import { ProjectComponent } from '../project/project.component';
import { LoggerService } from '../../services/logger-service';
import { appConfig } from '../../config';

export class ProjectSliderComponent extends React.Component {

  state = {
    activeSlide: 0,
    timestamp: Date.now()
  }

  constructor(props) {
    super(props);
    this.logger = new LoggerService();

    this.settings = {
      dots: appConfig.dots,
      arrows: false,
      adaptiveHeight: true,
      infinite: appConfig.infinite,
      speed: appConfig.speed,
      autoplay: appConfig.autoplay,
      autoplaySpeed: appConfig.autoplaySpeed,
      slidesToShow: 1,
      slidesToScroll: 1,
      mobileFirst: true,
      className: 'heliosSlide',
      beforeChange: (current, next) => {
        this.setState({ activeSlide: next, timestamp: Date.now() }); 
      }
    };
  }

  render() {

    let i = 0;

    return (
      <div>
      <Slider ref = {c => (this.slider = c)} {...this.settings}>
        {
          this.props.projectListId.data.map(projectId =>
              <ProjectComponent key={projectId} id={projectId} time={this.state.timestamp} originalIndex={ i++ } currentIndex = {this.state.activeSlide}></ProjectComponent>)
        }
      </Slider>
      </div>
    );
  }
}

ProjectComponent组件仅指定布局。这是App.js文件,我在其中加载projectslidercomponent和侧边栏。我这样做:

class App extends Component {

  state = {
    projectList: new ProjectListModel(),
    isLoading: true
  }

  constructor(props) {
    super(props);
    this.logger = new LoggerService();
  }



  componentDidMount() {
    let projectService = new ProjectService();
    projectService.getProjectList()
      .then(res => {
        let projectList = new ProjectListModel();
        projectList.data = res.data.data;
        this.setState({ projectList: projectList,
                        isLoading: false });
      })
      .catch(error => {
        this.logger.error(error);
      });
  }



  render() {
      return (
        <div className="App">
          <MySidebar>
            </MySidebar>
          <ProjectSliderComponent projectListId={this.state.projectList}></ProjectSliderComponent>
        </div>
      );
    }
}

export default App;

我需要做的是根据我单击的按钮来更改幻灯片。我需要做什么?是否像传递projectslidercomponent的“实例”并调用方法来更改幻灯片一样?还是其他?

2 个答案:

答案 0 :(得分:2)

在react-slick文档中,您可以了解slickGoTo,这是Slider组件的一种方法。

由于您已经存储了this.slider,因此可以尝试使其在MySidebar中可访问,并在调用changeSlide时使用它。您很有可能必须在顶层创建一个changeSlide方法,并将其作为属性传递给组件。

答案 1 :(得分:1)

要解决此问题,您需要做的是在父组件中创建一个函数,以更新应用程序组件的状态,状态更新后,它将重新渲染应用程序组件,并将新的道具发送到滑块组件,该组件将告诉显示哪个滑块。下面是代码:-

在App.js中

class App extends Component {

  state = {
    projectList: new ProjectListModel(),
    isLoading: true,
    menuId: 0
  }

  constructor(props) {
    super(props);
    this.logger = new LoggerService();
  }



  componentDidMount() {
    let projectService = new ProjectService();
    projectService.getProjectList()
      .then(res => {
        let projectList = new ProjectListModel();
        projectList.data = res.data.data;
        this.setState({ projectList: projectList,
                        isLoading: false });
      })
      .catch(error => {
        this.logger.error(error);
      });
  }

  ChangeSlide = (menuId) => {
   this.setState({
      menuId //Here you will receive which slide to show and according to that render slides in mySliderbar component
   })
  }



  render() {
      return (
        <div className="App">
          <MySidebar ChangeSlide={this.ChangeSlide} />
          <ProjectSliderComponent menuId={this.state.menuId} projectListId={this.state.projectList}></ProjectSliderComponent>
        </div>
      );
    }
}

export default App;

在mySlidebar中

import React from "react";
import './MySidebar.scss';
import {slide as Menu } from 'react-burger-menu'

export class MySidebar extends React.Component {


  constructor(props) {
    super(props);
  }


 changeSlide = (e) => {
   console.log("Clicked " + e.currentTarget.id); //get text content of
   this.props.changeSlide(e.currentTarget.id)
 }


  render() {


    return (
        <Menu customCrossIcon={false}>
            <button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project1">Project 1</button>
      <button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project2">Project 2</button>
        </Menu>
    );
  }
} 

在滑块组件中,您必须收听何时有新的道具出现,并根据滑块的变化来查看componentWillReceiveProps

import React from "react";
import Slider from "react-slick";
import './project-carousel.component.css';
import { ProjectComponent } from '../project/project.component';
import { LoggerService } from '../../services/logger-service';
import { appConfig } from '../../config';

export class ProjectSliderComponent extends React.Component {

  state = {
    activeSlide: 0,
    timestamp: Date.now()
  }

  constructor(props) {
    super(props);
    this.logger = new LoggerService();

    this.settings = {
      dots: appConfig.dots,
      arrows: false,
      adaptiveHeight: true,
      infinite: appConfig.infinite,
      speed: appConfig.speed,
      autoplay: appConfig.autoplay,
      autoplaySpeed: appConfig.autoplaySpeed,
      slidesToShow: 1,
      slidesToScroll: 1,
      mobileFirst: true,
      className: 'heliosSlide',
      beforeChange: (current, next) => {
        this.setState({ activeSlide: next, timestamp: Date.now() }); 
      }
    };
  }
  componentWillReceiveProps(nextProps) {
   if(nextprops.menuId != this.props.menuId){
    this.slider.slickGoTo(nextprops.menuId, true)//use slider instance to 
    //call the function to go to a particular slide.
   }
  }


  render() {

    let i = 0;
    const { menuId } = this.props
    return (
      <div>
      <Slider initialSlide={menuId} ref = {c => (this.slider = c)} {...this.settings}>
        {
          this.props.projectListId.data.map(projectId =>
              <ProjectComponent key={projectId} id={projectId} time={this.state.timestamp} originalIndex={ i++ } currentIndex = {this.state.activeSlide}></ProjectComponent>)
        }
      </Slider>
      </div>
    );
  }
}