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.
Top comments (0)