React-slick: Changing state of parent component on "beforeChange" callback breaks carousel

Created on 10 Dec 2016  路  3Comments  路  Source: akiran/react-slick

Hello,

I'm having an issue where I my carousel slides are created from a custom components. In order to style them properly, I need to know whether or not they are currently active.

My approach is: on 'beforeChange' callback, I set the carousel parent state to hold the index of the slide that will be displayed. That will cause a re-render, and, on the render method of the parent, I update the custom component's props to reflect if it's active or not.

This approach is causing the carousel to behave really weirdly.
I couldn't reproduce the exact same problem I'm having on my project, but I manage to find yet another one, that can be seen on the jsfiddle link.
https://jsfiddle.net/a9ygbzcu/

The issue I have in my project is shown on the attached video.
https://vimeo.com/195109205

Please note the console on the video.

If I just remove the setState part of my code, the carousel itself works fine.

If this is expected, how should I go over creating this logic to propagate to my component whether or not it is active?

Thanks!

All 3 comments

Just in case anyone else finds this issue, I came up with a (quite dirty) workaround.

import React, { PropTypes } from 'react';

class SliderWrapper extends React.Component {
  render() {
    const { className, children, tabIndex, style, 'data-index': dataIndex } = this.props;

    // since setting state of Slider's parent to keep track of
    // index of slide was causing bug, it was necessary to
    // use this hack to detect if the wrapper of the component
    // holds the active class, created by the Slider component.
    const active = className.indexOf('active') !== -1;

    return (
      <div
        className={className}
        tabIndex={tabIndex}
        style={style}
        data-index={dataIndex}
      >
        {React.cloneElement(children, {
          active,
        })}
      </div>
    );
  }
}

SliderWrapper.propTypes = {
  className: PropTypes.string,
  children: PropTypes.node,
  tabIndex: PropTypes.string,
  style: PropTypes.shape({}),
  'data-index': PropTypes.number,
};

export default SliderWrapper;

Use this component instead of a 'div' around your slide content.

This is a duplicate of or at least likely related to #136. Just noting that so all the discussion around this issue is easier to find. This issue should probably be closed to avoid getting more comments here.

Most people, on related issues, are claiming that setting state in any of beforeChange or afterChange hooks is causing the trouble. Please take a look at SlickGoTo example, this is somehow related to this. And I suppose that works just fine.

Was this page helpful?
0 / 5 - 0 ratings