Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clear a list of checkboxes in React

I have a few programatically generated lists of checkboxes (uncontrolled) in my project, and I'd like a react-way to clear them all at the click of a button. My problem is, I have no way to reference them each.

I've tried setting refs but I can't seem to figure out how to share refs between a stateless child and it's parent (is this even possible?)

All I need is a button that, when clicked, unchecks all checkboxes. I never would have imagined this would be so complicated but I've been at it for an hour now and my head is starting to spin. Here is an example of one of the lists:

{props.filters[0].map(jobType => (
  <li key={_.uniqueId('subType_')} className="checkbox text-sm m-b-sm">
    <label className="">
      <input type="checkbox" value={jobType.value} name="subtype" onChange={props.handleFilterCheck} />
      <span>{jobType.title}</span>
    </label>
    <span className="text-muted"></span>
  </li>
))}

So I have a way to consistently reference the size of the list and I know I could use iteration if I just had a way to reference the list but as it stands now that isn't possible. Any ideas?

like image 859
Robbie Milejczak Avatar asked Nov 20 '25 09:11

Robbie Milejczak


2 Answers

I've tried setting refs but I can't seem to figure out how to share refs between a stateless child and it's parent (is this even possible?)

It's not possible with functional components. refs only work on class components.

The other suggestion would be to convert all the checkbox to controlled inputs and then use props to pass in the checked state of false.

Or move the checkbox into it's own component that handles its own state:

{props.filters[0].map(jobType => (
    <li key={_.uniqueId('subType_')} className="checkbox text-sm m-b-sm">
        <CheckBox 
            value={jobType.value} 
            label={jobType.title}  
            onChange={props.handleFilterCheck}
            checked={/* Here you can manually override the checked state by passing in a bool */}
        />
        <span className="text-muted"></span>
    </li>
))}


class CheckBox extends Component {
    constructor (props) {
        super(props);
        this.state = {
            checked: props.checked || false
        }
    }
    render() {
        const { value, title, handleFilterCheck } = this.props;
        const { checked } = this.state;
        return (
            <label className="">
                <input type="checkbox" value={value} name="subtype" onChange={handleFilterCheck} checked={checked} />
                <span>{title}</span>
            </label>
        )
    }
}

EDIT:

And last but not least, you can straight up target all the elements and set checked to false using pure JS and dom manipulation.

document.querySelectorAll('input[type=checkbox]').forEach( el => el.checked = false );
like image 162
Chase DeAnda Avatar answered Nov 23 '25 00:11

Chase DeAnda


I managed to solve the same question by creating list of <Checkbox /> components. Then at parent level I used array state, which held all checked values. And one of the props to <Checkbox /> components was boolean which was telling if parent array state is empty.

const Parent = (someList) => {
  const [checkedArray,setCheckedArray] = useState([]);
  
  return(
    someList.map(el => <Checkbox key={el}
                                 empty={checkedArray.length === 0}
                                 value={el.value} /> 
                                 );
                                 );
                                 };
const Checkbox = ({empty, value}) => {
  const [checked, setChecked] = useState(false);
  
  useEffect(() => {
        empty && setChecked(false);
    }, [empty]);
    
  return(
    //some checkbox JSX
    );
    };

I'm newbie so there might be some pitfalls.

like image 37
SunRock Baitulla Avatar answered Nov 22 '25 22:11

SunRock Baitulla