BackbonePrincess
BackbonePrincess

Reputation: 25

Using React Higher Order Component - Specifically react-sortable-hoc with redux

I am having trouble understanding a very basic part of this HOC that has a good traction on NPM so I am guessing there is an obvious answer here I am missing.

I have a TabListComponent which renders a list from a redux store:

return this.props.tabs.map((tab) => {
    return (<li>{tab.title}</li>) 
})

In my MainComponent class, I am importing the TabListComponent and the react-sortable-hoc

import TabListComponent from './tabListComponent';
import { SortableContainer, SortableElement, arrayMove } from 'react-sortable-hoc';

I'm trying not to deviate too much from the documentation, so this is how I'm rendering the components

const SortableItem = SortableElement(TabListComponent); //I wrap TabListComponent directly 

const SortableList = SortableContainer(() => {
    return (
        <ul className="tabs-inline-block">
            <SortableItem />
        </ul>
    );
});
onSortEnd () {
    console.log("I don't need a callback, but this gets called anyway. Is this necessary?");
}

render () {
    return (
        <div>
            <SortableList axis={'x'} onSortEnd={this.onSortEnd}/>
        </div>
    )
}

Initial enter image description here

While dragging initial

Upvotes: 1

Views: 1142

Answers (1)

wpcarro
wpcarro

Reputation: 1546

A stylistic concern: you should refactor your TabListComponent...

return this.props.tabs.map(({title}) => <li>{title}</li>)

More importantly, your SortableList is not valid for React. I think refactoring it would help greatly.

const SortableItem = SortableElement(TabListComponent);

const SortableList = SortableContainer(({items}) =>
  <ul className="tabs-inline-block">
    {items.map((item, i) =>
      <SortableItem
        key={i}
        index={i}
        title={item.title}  // assumes `item` has a title property
      />
    )}
  </ul>
);

class SortableComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [{title: 'one'}, {title: 'two'}]
    };
  }

  onSortEnd({old, new}) {
    this.setState({
      items: arrayMove(this.state.items, old, new)
    });
  }

  render() {
    return (
      <SortableList
        items={this.state.items} // put your item models here
        onSortEnd={this.onSortEnd.bind(this)}
      />
    );
  }
}

You might want to read up more on ES6 classes. Look at their analogues in ES5 using object literals. If you're new to Javascript or ES6, React tutorials can sometimes be hard to follow. Things like...

method() {
  return 2 + 3;
}

...cannot exist on their own. They must be wrapped in an object literal or a class. e.g.

const x = {
  method() {
    return 2 + 3;
  }
};

Upvotes: -2

Related Questions