title: React js - material ui - transfer list -- using old states
body: <p>I'm making a react application and trying to recreate this transfer list demo on the material ui - to use the old method of states. but I've fallen into some traps.</p>
  <p>current sandbox
  <a href="https://codesandbox.io/s/morning-voice-qrym9?file=/src/TransferList.js" rel="nofollow noreferrer">https://codesandbox.io/s/morning-voice-qrym9?file=/src/TransferList.js</a></p>
  <p><a href="https://material-ui.com/components/transfer-list/" rel="nofollow noreferrer">https://material-ui.com/components/transfer-list/</a> -- basing it off the simple list - I am trying to recreate this as a component - to follow on from how the rest of the components have been built - but something in the declaration of the functions and states is causing a ripple effect of errors</p>
  <p>my current code.</p>
  <pre><code>import React, { Component } from 'react'
  import { withRouter } from 'react-router-dom';
  import { connect } from 'react-redux';
  import { bindActionCreators } from 'redux';
  
  
  import Grid from '@material-ui/core/Grid';
  import List from '@material-ui/core/List';
  import Card from '@material-ui/core/Card';
  import CardHeader from '@material-ui/core/CardHeader';
  import ListItem from '@material-ui/core/ListItem';
  import ListItemText from '@material-ui/core/ListItemText';
  import ListItemIcon from '@material-ui/core/ListItemIcon';
  import Checkbox from '@material-ui/core/Checkbox';
  import Button from '@material-ui/core/Button';
  import Divider from '@material-ui/core/Divider';
  
  
  import './TransferList.scss';
  
  class TransferList extends Component {
    
    constructor(props, context) {
      super(props, context);
      this.state = {
        checked: [],
        left: [0, 1, 2, 3],
        right: [4, 5, 6, 7]
      };
    }
  
  
    not(a, b) {
      //return a.filter((value) =&gt; b.indexOf(value) === -1);
    }
  
    intersection(a, b) {
      //return a.filter((value) =&gt; b.indexOf(value) !== -1);
    }
  
    union(a, b) {
      //return [...a, ...this.not(b, a)];
    }
  
  
  
    numberOfChecked(items) {
      //return this.intersection(this.state.checked, items).length;
    }
  
    handleToggleAll(items) {
      if (this.numberOfChecked(items) === items.length) {
  
        this.state = {
          checked: this.not(this.state.checked, items),
        };
      } else {
  
        this.state = {
          checked: this.union(this.state.checked, items),
        };
      }
    };
    
    handleCheckedRight() {
     const leftChecked = this.intersection(this.state.checked, this.state.left);
      this.state = {
        right: this.state.right.concat(leftChecked),
        left: this.not(this.state.left, leftChecked),
        checked: this.not(this.state.checked, leftChecked),
      };
    };
  
    handleCheckedLeft() {
     const rightChecked = this.intersection(this.state.checked, this.state.right);
  
      this.state = {
        right: this.not(this.state.right, rightChecked),
        left: this.state.left.concat(rightChecked),
        checked: this.not(this.state.checked, rightChecked),
      };
    };
  
   customList(title, items) {
    return (
        &lt;Card&gt;
          &lt;CardHeader
            //className={classes.cardHeader}
            avatar={
              &lt;Checkbox
                onClick={this.handleToggleAll(items)}
                checked={this.numberOfChecked(items) === items.length &amp;&amp; items.length !== 0}
                indeterminate={this.numberOfChecked(items) !== items.length &amp;&amp; this.numberOfChecked(items) !== 0}
                disabled={items.length === 0}
                inputProps={{ 'aria-label': 'all items selected' }}
              /&gt;
            }
            title={title}
            subheader={`${this.numberOfChecked(items)}/${items.length} selected`}
          /&gt;
          &lt;Divider /&gt;
          &lt;List 
            //className={classes.list} 
            dense 
            component=&quot;div&quot; 
            role=&quot;list&quot;
          &gt;
            
            &lt;ListItem /&gt;
          &lt;/List&gt;
        &lt;/Card&gt;
      );
   }
  
  
  
    render() {
  
  
  
      const leftChecked = this.intersection(this.state.checked, this.state.left);
      const rightChecked = this.intersection(this.state.checked, this.state.right);
  /*
      const handleToggle = (value) =&gt; () =&gt; {
        const currentIndex = checked.indexOf(value);
        const newChecked = [...checked];
  
        if (currentIndex === -1) {
          newChecked.push(value);
        } else {
          newChecked.splice(currentIndex, 1);
        }
  
        setChecked(newChecked);
      };
  
      const numberOfChecked = (items) =&gt; this.intersection(checked, items).length;
  
      const handleToggleAll = (items) =&gt; () =&gt; {
        if (numberOfChecked(items) === items.length) {
          setChecked(not(checked, items));
        } else {
          setChecked(union(checked, items));
        }
      };
  
      const handleCheckedRight = () =&gt; {
        setRight(right.concat(leftChecked));
        setLeft(not(left, leftChecked));
        setChecked(not(checked, leftChecked));
      };
  
      const handleCheckedLeft = () =&gt; {
        setLeft(left.concat(rightChecked));
        setRight(not(right, rightChecked));
        setChecked(not(checked, rightChecked));
      };
  
      const customList = (title, items) =&gt; (
        &lt;Card&gt;
          &lt;CardHeader
            className={classes.cardHeader}
            avatar={
              &lt;Checkbox
                onClick={handleToggleAll(items)}
                checked={numberOfChecked(items) === items.length &amp;&amp; items.length !== 0}
                indeterminate={numberOfChecked(items) !== items.length &amp;&amp; numberOfChecked(items) !== 0}
                disabled={items.length === 0}
                inputProps={{ 'aria-label': 'all items selected' }}
              /&gt;
            }
            title={title}
            subheader={`${numberOfChecked(items)}/${items.length} selected`}
          /&gt;
          &lt;Divider /&gt;
          &lt;List className={classes.list} dense component=&quot;div&quot; role=&quot;list&quot;&gt;
            {items.map((value) =&gt; {
              const labelId = `transfer-list-all-item-${value}-label`;
  
              return (
                &lt;ListItem key={value} role=&quot;listitem&quot; button onClick={handleToggle(value)}&gt;
                  &lt;ListItemIcon&gt;
                    &lt;Checkbox
                      checked={checked.indexOf(value) !== -1}
                      tabIndex={-1}
                      disableRipple
                      inputProps={{ 'aria-labelledby': labelId }}
                    /&gt;
                  &lt;/ListItemIcon&gt;
                  &lt;ListItemText id={labelId} primary={`List item ${value + 1}`} /&gt;
                &lt;/ListItem&gt;
              );
            })}
            &lt;ListItem /&gt;
          &lt;/List&gt;
        &lt;/Card&gt;
      );
  
  */
  
  
      return (
        &lt;Grid container spacing={2} justify=&quot;center&quot; alignItems=&quot;center&quot;&gt;
          &lt;Grid item&gt;{this.customList('Choices', this.state.left)}&lt;/Grid&gt;
          &lt;Grid item&gt;
            &lt;Grid container direction=&quot;column&quot; alignItems=&quot;center&quot;&gt;
              &lt;Button
                variant=&quot;outlined&quot;
                size=&quot;small&quot;
                //className={classes.button}
                onClick={this.handleCheckedRight}
                disabled={leftChecked.length === 0}
                aria-label=&quot;move selected right&quot;
              &gt;
                &amp;gt;
              &lt;/Button&gt;
              &lt;Button
                variant=&quot;outlined&quot;
                size=&quot;small&quot;
                //className={classes.button}
                onClick={this.handleCheckedLeft}
                disabled={rightChecked.length === 0}
                aria-label=&quot;move selected left&quot;
              &gt;
                &amp;lt;
              &lt;/Button&gt;
            &lt;/Grid&gt;
          &lt;/Grid&gt;
          &lt;Grid item&gt;{this.customList('Chosen', this.state.right)}&lt;/Grid&gt;
        &lt;/Grid&gt;
      )
    }
  }
  
  
  function mapStateToProps(state) {
    return {
    };
  }
  
  function mapDispatchToProps(dispatch) {
   return bindActionCreators({  }, dispatch);
  }
  
  export default withRouter(connect(mapStateToProps, mapDispatchToProps)(TransferList))
  
  
  
  ////////
  
  /*
  
  export default function TransferList() {
    const classes = useStyles();
    const [checked, setChecked] = React.useState([]);
    const [left, setLeft] = React.useState([0, 1, 2, 3]);
    const [right, setRight] = React.useState([4, 5, 6, 7]);
  
    const leftChecked = intersection(checked, left);
    const rightChecked = intersection(checked, right);
  
    const handleToggle = (value) =&gt; () =&gt; {
      const currentIndex = checked.indexOf(value);
      const newChecked = [...checked];
  
      if (currentIndex === -1) {
        newChecked.push(value);
      } else {
        newChecked.splice(currentIndex, 1);
      }
  
      setChecked(newChecked);
    };
  
    const numberOfChecked = (items) =&gt; intersection(checked, items).length;
  
    const handleToggleAll = (items) =&gt; () =&gt; {
      if (numberOfChecked(items) === items.length) {
        setChecked(not(checked, items));
      } else {
        setChecked(union(checked, items));
      }
    };
  
    const handleCheckedRight = () =&gt; {
      setRight(right.concat(leftChecked));
      setLeft(not(left, leftChecked));
      setChecked(not(checked, leftChecked));
    };
  
    const handleCheckedLeft = () =&gt; {
      setLeft(left.concat(rightChecked));
      setRight(not(right, rightChecked));
      setChecked(not(checked, rightChecked));
    };
  
    const customList = (title, items) =&gt; (
      &lt;Card&gt;
        &lt;CardHeader
          className={classes.cardHeader}
          avatar={
            &lt;Checkbox
              onClick={handleToggleAll(items)}
              checked={numberOfChecked(items) === items.length &amp;&amp; items.length !== 0}
              indeterminate={numberOfChecked(items) !== items.length &amp;&amp; numberOfChecked(items) !== 0}
              disabled={items.length === 0}
              inputProps={{ 'aria-label': 'all items selected' }}
            /&gt;
          }
          title={title}
          subheader={`${numberOfChecked(items)}/${items.length} selected`}
        /&gt;
        &lt;Divider /&gt;
        &lt;List className={classes.list} dense component=&quot;div&quot; role=&quot;list&quot;&gt;
          {items.map((value) =&gt; {
            const labelId = `transfer-list-all-item-${value}-label`;
  
            return (
              &lt;ListItem key={value} role=&quot;listitem&quot; button onClick={handleToggle(value)}&gt;
                &lt;ListItemIcon&gt;
                  &lt;Checkbox
                    checked={checked.indexOf(value) !== -1}
                    tabIndex={-1}
                    disableRipple
                    inputProps={{ 'aria-labelledby': labelId }}
                  /&gt;
                &lt;/ListItemIcon&gt;
                &lt;ListItemText id={labelId} primary={`List item ${value + 1}`} /&gt;
              &lt;/ListItem&gt;
            );
          })}
          &lt;ListItem /&gt;
        &lt;/List&gt;
      &lt;/Card&gt;
    );
  
  
  */
  
  //////////
  </code></pre>
  <p>latest sandbox working
  <a href="https://codesandbox.io/s/morning-voice-qrym9?file=/src/TransferList.js" rel="nofollow noreferrer">https://codesandbox.io/s/morning-voice-qrym9?file=/src/TransferList.js</a></p>