React-slick: prevArrow and nextArrow don't seem to like react components

Created on 18 Apr 2016  路  8Comments  路  Source: akiran/react-slick

I was trying to use our own custom components for prevArrow and nextArrow, and I was getting all kinds of invariant violations from react.

https://www.dropbox.com/s/kyhmhrf1u60qg6s/Screenshot%202016-04-18%2009.23.37.png?dl=0

my Arrow code looks like this.

import React from 'react'
import { FloatingActionButton } from 'material-ui'

import NavigationChevronLeft from 'material-ui/svg-icons/navigation/chevron-left'
import NavigationChevronRight from 'material-ui/svg-icons/navigation/chevron-right'

export default class SliderArrow extends React.Component {
  render () {
    const {
      children,
      onClick: onTouchTap,
      side,
      ...props
    } = this.props

    const style = {
      opacity: 0.6,
      position: 'absolute',
      top: '50%',
      transform: 'translateY(-50%)'
    }

    style[side] = '3%'

    return (
      <FloatingActionButton {...props} mini onTouchTap={onTouchTap} style={style}>
        {children}
      </FloatingActionButton>
    )
  }
}

SliderArrow.propTypes = {
  children: React.PropTypes.node,
  side: React.PropTypes.string.isRequired,
  onClick: React.PropTypes.func
}

export const SliderArrowPrev = <SliderArrow side='left'><NavigationChevronLeft /></SliderArrow>
export const SliderArrowNext = <SliderArrow side='right'><NavigationChevronRight /></SliderArrow>

And then for the slider itself.

const SliderProps = {
  dots: false,
  draggable: false,
  infinite: true,
  nextArrow: SliderArrowNext,
  pauseOnHover: true,
  prevArrow: SliderArrowPrev,
  slidesToScroll: 1,
  slidesToShow: 1,
  speed: 500,
  touchMove: false
}

<Slider {...SliderProps} beforeChange={beforeChange}>

I dug around in the code a little big and it looks like you are using React.createElement on whatever is sent in. I changed both of these calls to React.cloneElement and then it seems to have no problem tackling the components and all the custom properties I set still work.

Most helpful comment

It would be nice to have an ES6 example, though. This seems to be a pretty uncommon way of declaring Components. Unless we're just arriving at not using Components, which is definitely different than what the documentation suggests. :/

Facebook does plan to deprecate React.createClass

All 8 comments

@sorahn So how you managed to set custom navigation buttons?

Using cloneElement is not compatible with the documentation's proposed method of using custom arrow buttons. cloneElement will not work on a React Class, only on a React Element. Either the docs should specify passing in an element, instead of a class, or createElement should be used.

I like the cloneElement approach. Passing in elements is also how Material-UI works. The docs should give an example, something like:

class LeftNavButton extends React.Component {
  render() {
    return <button {...this.props}>Next</button>  
  }
}
...
<Slider prevArrow={ <LeftNavButton /> } />

@Azael05x I ended up with something like this.

``` .js
function SliderButton ({ children, onClick }) {
return
}

class App extends Component {
// ...
render () {
return (
nextArrow={}
prevArrow={}
/>
)
}
}
```

The example in the docs still doesn't work or isn't clear. If I pass the react class as the nextArrow prop it uses default nextArrow (nextArrow: MyNextArrow), and if I pass react element (nextArrow: <MyNextArrow />) I get all the invariant errors as @sorahn did in his screenshot.

I struggled with customizing the prev and next buttons, here's where I landed after failing to get the example in docs to work. An example based on @sorahn and what was in the docs:

export default class Home extends Component {

  render() {
    function PrevButton({ onClick }) {
      return <button onClick={onClick} className="slick-prev" style={{ left: 0 }}>Prev</button>;
    }

    function NextButton({ onClick }) {
      return <button onClick={onClick} className="slick-next" style={{ right: 0 }}>Next</button>;
    }

    const settings = {
      dots: true,
      infinite: true,
      speed: 500,
      slidesToShow: 1,
      slidesToScroll: 1,
      dotsClass: cx('slick-dots', styles.dots),
      prevArrow: <PrevButton />,
      nextArrow: <NextButton />,
    };

    return (
      <div>
        <Helmet title="Home" />
        <div className="center">
          <Slider {...settings}>

This example works https://github.com/akiran/react-slick/blob/master/examples/CustomArrows.js

You can check by running demos locally

It would be nice to have an ES6 example, though. This seems to be a pretty uncommon way of declaring Components. Unless we're just arriving at not using Components, which is definitely different than what the documentation suggests. :/

Facebook does plan to deprecate React.createClass

Was this page helpful?
0 / 5 - 0 ratings

Related issues

PolGuixe picture PolGuixe  路  3Comments

amishPro picture amishPro  路  3Comments

rohitgoyal7 picture rohitgoyal7  路  3Comments

jfamousket picture jfamousket  路  3Comments

Exomnius picture Exomnius  路  3Comments