DEV Community

loading...
Cover image for Dynamically Create Toggle Switch List for Attendance w/ Hooks & MaterialUI

Dynamically Create Toggle Switch List for Attendance w/ Hooks & MaterialUI

Brad Beggs
Curious and Persistent.
・3 min read

Who This Is For

*You are creating a list with true/false options, such as an attendance list.
*You are trying to use useState with an object and/or array and it won’t work.
*You want a codesand box with clear explanations of how & why.

Note - This is Typescript. If you are new to Typescript, know this bit of code: : boolean or : string after a variable declaration indicates the data type to check for. Otherwise, the implementation is the same.

Sandbox

Step 1 - Setup Initial Form Structure

Once you have the bones of your form ready, the first key to dynamically creating toggle switches is the code below:

<FormGroup>
        {attendees.map((member, i) => {
            return (    
              <ListMembers             // ListMembers component creates the toggle switches
              key={i}                        // the ID React uess to track unique components and state changes
              member={member}    // an unique index from attendees array, containing a member object
              memberIdx={i}           // the array index number, needed for handleChange
              handleAttendingChange={handleAttendingChange}   
              />
            )
          })}
      </FormGroup> 
Enter fullscreen mode Exit fullscreen mode

<FormGroup> is a MaterialUI group that nests the MaterialUI <Switch> component. Between the <FormGroup> is a map() of the data (from state) to create the attendance list, in this case using attendees.

Please review the code comments to understand why each prop is listed.

Step 2 - Setup the Toggle Component

A simple component. The important aspect is the arguments passed to the onChange callback.

onChange={() =>{ handleAttendingChange(memberIdx, !member.isAttending)}}  

Enter fullscreen mode Exit fullscreen mode

The ! lets the state flip-flop, otherwise state does not change. Only the array index of the member (memberIdx) is passback; we have access to the member object in the parent component so we only need a reference passed.

Step 3 - Handle The Change Function

Most toggle tutorials statically set a toggle value (see Resources below for useful articles on this method).

However, we need a dynamic method as we are working with an array of objects. As such, the handleChange setState is implemented differently.

const updatedAttendee = attendees[memberIdx]  // from the state 'attendees' array, get the correct object for updatedAttendee
    updatedAttendee.isAttending = attendanceState // update the boolean of the attendee to indicate going/true || not/false

    const newAttendees = [...attendees]           // make a copy of previous state of attendees
    newAttendees[memberIdx] = updatedAttendee     // insert/overwrite array object of the attendee in question with the new version
    setAttendees(newAttendees)                    // update state  
Enter fullscreen mode Exit fullscreen mode

Unlike SetState in a React class, useState overwrites the previous state, rather than mutating it AND in order for React to know of a state change, ‘useState’ needs a new object. The 5 lines of code above creates the new object.

To understand the details on useState for arrays and objects, check out:
*A Guide to To UseState
and these two videos:
*React Hooks Tutorial - 4 - useState with object
*React Hooks Tutorial - 5 - useState with array

Step 5 - Submit The Form

For the demo, fairy tale creatures who can attend are filtered into a separate list and considered submitted.

How you POST/PATCH to your backend is unique and not covered here.

Aside - Why Not Use Event.Target?

Event.target.value is only useful for form elements with changing values.” - Andre
“If you had an input [textbox] with an onChange handler, then you'd want the event.target.value.” -Andre

A toggle property’s name is checked but all we need is the value (true/false) and pass back this value via a prop, member.isAttending in this demo.

Feedback?

Have thoughts or advice on the above implementation?

If so, drop a note. I'd love to hear and see your examples, explanations, and other details to clarify how/why/when.

Resources

A Guide to To UseState
React Hooks Tutorial - 4 - useState with object
React Hooks Tutorial - 5 - useState with array
Static Toggle - Create a Toggle Switch in React as a Reusable Component
StackOverFlow Conversation on Submitting a Form
MaterialUI Switch - Official Documentation

Special Thanks

Thanks to my dear friend Andre for walking me through the issues I had with the handleChange and which props to pass.

Discussion (0)