title: TransferList is so slow
body: <p>I made faster TextField and Select referring to below.</p>
  <p><a href="https://stackoverflow.com/questions/64706801/textfield-unnecessary-re-renders">TextField Unnecessary Re-renders</a></p>
  <p>But even though I used useMemo TransferList could make faster just a little.
  <br>
  My current code is here:</p>
  <pre><code>import Grid from &quot;@mui/material/Grid&quot;;
  import List from &quot;@mui/material/List&quot;;
  import ListItem from &quot;@mui/material/ListItem&quot;;
  import ListItemIcon from &quot;@mui/material/ListItemIcon&quot;;
  import ListItemText from &quot;@mui/material/ListItemText&quot;;
  import Checkbox from &quot;@mui/material/Checkbox&quot;;
  import Button from &quot;@mui/material/Button&quot;;
  import Paper from &quot;@mui/material/Paper&quot;;
  import React, { useMemo } from &quot;react&quot;;
  
  interface TransferListProps {
    items: any;
    setData: (value: any) =&gt; void;
  }
  
  interface Props {
    customList: any;
    right: any[];
    left: any[];
    handleAllRight: any;
    handleCheckedRight: any;
    leftChecked: any;
    handleCheckedLeft: any;
    rightChecked: any;
    handleAllLeft: any;
  }
  
  function not(a: readonly number[], b: readonly number[]) {
    console.log(a.filter((value) =&gt; b.indexOf(value) === -1));
    return a.filter((value) =&gt; b.indexOf(value) === -1);
  }
  
  function intersection(a: readonly number[], b: readonly number[]) {
    return a.filter((value) =&gt; b.indexOf(value) !== -1);
  }
  
  const TransferListComponent = React.memo((props: Props) =&gt; {
    return (
      &lt;Grid container spacing={2} justifyContent=&quot;start&quot; alignItems=&quot;center&quot;&gt;
        &lt;Grid item&gt;{props.customList(props.left)}&lt;/Grid&gt;
        &lt;Grid item&gt;
          &lt;Grid container direction=&quot;column&quot; alignItems=&quot;center&quot;&gt;
            &lt;Button
              sx={{ my: 0.5 }}
              variant=&quot;outlined&quot;
              size=&quot;small&quot;
              onClick={props.handleAllRight}
              disabled={props.left.length === 0}
              aria-label=&quot;move all right&quot;
            &gt;
              ≫
            &lt;/Button&gt;
            &lt;Button
              sx={{ my: 0.5 }}
              variant=&quot;outlined&quot;
              size=&quot;small&quot;
              onClick={props.handleCheckedRight}
              disabled={props.leftChecked.length === 0}
              aria-label=&quot;move selected right&quot;
            &gt;
              &amp;gt;
            &lt;/Button&gt;
            &lt;Button
              sx={{ my: 0.5 }}
              variant=&quot;outlined&quot;
              size=&quot;small&quot;
              onClick={props.handleCheckedLeft}
              disabled={props.rightChecked.length === 0}
              aria-label=&quot;move selected left&quot;
            &gt;
              &amp;lt;
            &lt;/Button&gt;
            &lt;Button
              sx={{ my: 0.5 }}
              variant=&quot;outlined&quot;
              size=&quot;small&quot;
              onClick={props.handleAllLeft}
              disabled={props.right.length === 0}
              aria-label=&quot;move all left&quot;
            &gt;
              ≪
            &lt;/Button&gt;
          &lt;/Grid&gt;
        &lt;/Grid&gt;
        &lt;Grid item&gt;{props.customList(props.right)}&lt;/Grid&gt;
      &lt;/Grid&gt;
    );
  });
  
  export default function TransferList(props: TransferListProps) {
    const [checked, setChecked] = React.useState&lt;readonly any[]&gt;([]);
    const [left, setLeft] = React.useState&lt;any[]&gt;(
      props.items.map((value: any) =&gt; {
        return value.name;
      })
    );
    const [right, setRight] = React.useState&lt;any[]&gt;([]);
  
    const leftChecked = intersection(checked, left);
    const rightChecked = intersection(checked, right);
  
    const handleToggle = useMemo(
      () =&gt; (value: number) =&gt; () =&gt; {
        const currentIndex = checked.indexOf(value);
        const newChecked = [...checked];
        if (currentIndex === -1) {
          newChecked.push(value);
        } else {
          newChecked.splice(currentIndex, 1);
        }
        setChecked(newChecked);
      },
      [rightChecked]
    );
  
    const handleAllRight = useMemo(
      () =&gt; () =&gt; {
        setRight(right.concat(left));
        props.setData(right.concat(left));
        setLeft([]);
      },
      [rightChecked]
    );
  
    const handleCheckedRight = useMemo(
      () =&gt; () =&gt; {
        setRight(right.concat(leftChecked));
        props.setData(right.concat(leftChecked));
        setLeft(not(left, leftChecked));
        setChecked(not(checked, leftChecked));
      },
      [rightChecked]
    );
  
    const handleCheckedLeft = useMemo(
      () =&gt; () =&gt; {
        setLeft(left.concat(rightChecked));
        setRight(not(right, rightChecked));
        props.setData(not(right, rightChecked));
        setChecked(not(checked, rightChecked));
      },
      [rightChecked]
    );
  
    const handleAllLeft = useMemo(
      () =&gt; () =&gt; {
        setLeft(left.concat(right));
        setRight([]);
        props.setData([]);
      },
      [rightChecked]
    );
  
    const customList = useMemo(
      () =&gt; (items: string[]) =&gt;
        (
          &lt;Paper sx={{ width: 175, height: 230, overflow: &quot;auto&quot; }}&gt;
            &lt;List dense component=&quot;div&quot; role=&quot;list&quot;&gt;
              {items.map((value: any) =&gt; {
                const labelId = `transfer-list-item-${value}-label`;
                const randomNumber = Math.random();
  
                return (
                  &lt;ListItem
                    key={randomNumber}
                    role=&quot;listitem&quot;
                    button
                    onClick={handleToggle(value)}
                  &gt;
                    &lt;ListItemIcon&gt;
                      &lt;Checkbox
                        checked={checked.indexOf(value) !== -1}
                        tabIndex={-1}
                        disableRipple
                        inputProps={{
                          &quot;aria-labelledby&quot;: labelId,
                        }}
                      /&gt;
                    &lt;/ListItemIcon&gt;
                    &lt;ListItemText id={labelId} primary={`${value}`} /&gt;
                  &lt;/ListItem&gt;
                );
              })}
              &lt;ListItem /&gt;
            &lt;/List&gt;
          &lt;/Paper&gt;
        ),
      [rightChecked]
    );
  
    return (
      &lt;TransferListComponent
        customList={customList}
        left={left}
        right={right}
        handleAllRight={handleAllRight}
        handleCheckedRight={handleCheckedRight}
        leftChecked={leftChecked}
        handleCheckedLeft={handleCheckedLeft}
        rightChecked={rightChecked}
        handleAllLeft={handleAllLeft}
      /&gt;
    );
  }
  
  </code></pre>
  <p>This is the relation to describe parent and child.</p>
  <p><code>UsersSearch</code> → <code>TransferList</code> → <code>TransferListComponent</code></p>
  <p>Could you give me advise?
  <br>
  Thank you.</p>