1
\$\begingroup\$

all.
This component is meant to take in an array of available options and provide the user an easy way to choose multiple options. Each time the selected options are changed/updated, those options are console logged.

I'm hoping that someone could provide any criticism on my current code. I want to make sure that the code is as simple and clean as it could be, while keeping all logic outside of the JSX. Photo of component at bottom of post.

Thanks in advance!

const label = 'Select options';
const availableOptionsLabel = 'Available Types';
const selectedOptionsLabel = 'Selected Types';

export default function MultiSelection({options=['A', 'B', 'C']}) {
  const [availableOptions, setAvailableOptions] = useState([]);
  const [selectedOptions, setSelectedOptions] = useState([]);

  useEffect(() => {
    setAvailableOptions(options);
  }, []);

  useEffect(() => {
    console.log('Updated selection is: ', JSON.stringify(selectedOptions));
  }, [selectedOptions]);

  const row = (text, key, whichColumn, action) => {
    return(
      <div key={`${whichColumn}-button-row-${key}`} className='button-row-container' onClick={() => action(text)}>
        <IconButtonRow>
          <IconButton id='add' iconClass='icon-add'/>
          <p>{text}</p>
        </IconButtonRow>
      </div>
    )
  }

  const moveToAvailableOptions = clickedOption => {
    setAvailableOptions([...availableOptions, clickedOption]);
    let tempSelectedOptions = [...selectedOptions.filter(option => option !== clickedOption)];
    setSelectedOptions(tempSelectedOptions);
  }

  const moveToSelectedOptions = clickedOption => {
    setSelectedOptions([...selectedOptions, clickedOption]);
    let tempAvailableOptions = [...availableOptions.filter(option => option !== clickedOption)];
    setAvailableOptions(tempAvailableOptions);
  }

  return(
    <div className='multi-selection'>
      <h5>{label}</h5>
      <div className='label-containter'>
        <h6 className='available-options-label'>{availableOptionsLabel}</h6>
        <h6 className='selected-options-label'>{selectedOptionsLabel}</h6>
      </div>
      <div className='options-containter'>
        <div className='available-options'>
          {availableOptions.map((option, key) => row(option, key, 'available', moveToSelectedOptions))}
        </div>

        <div className='selected-options'>
          {selectedOptions.map((option, key) => row(option, key, 'selected', moveToAvailableOptions))}
        </div>
      </div>
    </div>
  )
}

enter image description here

\$\endgroup\$
  • 1
    \$\begingroup\$ Looks fine, except for the lets (prefer const) and a few missing semicolons (for both, consider a linter) \$\endgroup\$ – CertainPerformance May 12 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.