Dynamically Create Toggle Switch List for Attendance w/ Hooks & MaterialUI
Brad Beggs
Posted on December 24, 2020
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>
<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)}}
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
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.
Posted on December 24, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.